Skip to content

Commit

Permalink
introduce index tables, add liq fee fixed to 0.01%
Browse files Browse the repository at this point in the history
  • Loading branch information
sergioyuhjtman committed Nov 10, 2020
1 parent b18827b commit 0a3b05c
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 15 deletions.
5 changes: 3 additions & 2 deletions evolutiondex.contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,9 @@ summary: '{{nowrap user}} buys an evotoken by adding liquidity to pools'
The first asset to be paid by {{user}} is computed as x + y, where

x = pool1 * {{to_buy}} / supply, up to the precision of the symbol of pool1 rounded upward.
y = x * fee / 10000, up to the same precision as x, again rounded upward.
The variables pool1, supply, fee denote the parameters pool1, supply, fee associated to the token {{asset_to_symbol_code to_buy}} respectively, at the moment of operation.
y = x / 10000, up to the same precision as x, again rounded upward.
The variables pool1 and supply denote the values pool1 and supply associated to
the token {{asset_to_symbol_code to_buy}} respectively, at the moment of operation.

The second asset to be paid by {{user}} is computed analogously.

Expand Down
51 changes: 42 additions & 9 deletions evolutiondex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ void evolutiondex::add_signed_liq(name user, asset to_add, bool is_buying,
auto P1 = token-> pool1.quantity.amount;
auto P2 = token-> pool2.quantity.amount;

int fee = is_buying? token->fee : 0;
int fee = is_buying? ADD_LIQUIDITY_FEE : 0;
auto to_pay1 = extended_asset{ asset{compute(to_add.amount, P1, A, fee),
token->pool1.quantity.symbol}, token->pool1.contract};
auto to_pay2 = extended_asset{ asset{compute(to_add.amount, P2, A, fee),
Expand All @@ -125,7 +125,7 @@ void evolutiondex::add_signed_liq(name user, asset to_add, bool is_buying,
a.pool1 += to_pay1;
a.pool2 += to_pay2;
});
if (token-> supply.amount == 0) statstable.erase(token);
check(token->supply.amount != 0, "the pool cannot be left empty");
}

void evolutiondex::exchange( name user, symbol_code pair_token,
Expand Down Expand Up @@ -200,38 +200,64 @@ void evolutiondex::inittoken(name user, symbol new_symbol, extended_asset initia
extended_asset initial_pool2, int initial_fee, name fee_contract)
{
require_auth( user );
require_auth( get_self() );
check((initial_pool1.quantity.amount > 0) && (initial_pool2.quantity.amount > 0), "Both assets must be positive");
check((initial_pool1.quantity.amount < INIT_MAX) && (initial_pool2.quantity.amount < INIT_MAX), "Initial amounts must be less than 10^15");
uint8_t new_precision = ( initial_pool1.quantity.symbol.precision() + initial_pool2.quantity.symbol.precision() ) / 2;
check( new_symbol.precision() == new_precision, "new_symbol precision must be (precision1 + precision2) / 2" );
int128_t geometric_mean = sqrt(int128_t(initial_pool1.quantity.amount) * int128_t(initial_pool2.quantity.amount));
auto new_token = asset{int64_t(geometric_mean), new_symbol};
check( initial_pool1.get_extended_symbol() != initial_pool2.get_extended_symbol(), "extended symbols must be different");
stats statstable( get_self(), new_token.symbol.code().raw() );
const auto& token = statstable.find( new_token.symbol.code().raw() );

stats statstable( get_self(), new_symbol.code().raw() );
const auto& token = statstable.find( new_symbol.code().raw() );
check ( token == statstable.end(), "token symbol already exists" );
check( (0 <= initial_fee) && (initial_fee <= 500), "initial fee out of reasonable range");
check( is_account(fee_contract) || !fee_contract, "fee_contract account must exist or be empty");
check( initial_fee == DEFAULT_FEE, "initial_fee must be 10");
check( fee_contract == "wevotethefee"_n, "fee_contract must be wevotethefee");

statstable.emplace( user, [&]( auto& a ) {
a.supply = new_token;
a.max_supply = asset{MAX,new_token.symbol};
a.max_supply = asset{MAX,new_symbol};
a.issuer = get_self();
a.pool1 = initial_pool1;
a.pool2 = initial_pool2;
a.fee = initial_fee;
a.fee_contract = fee_contract;
} );

placeindex(user, new_symbol, initial_pool1, initial_pool2 );
add_balance(user, new_token, user);
add_signed_ext_balance(user, -initial_pool1);
add_signed_ext_balance(user, -initial_pool2);
}

void evolutiondex::indexpair(name user, symbol evo_symbol) {
stats statstable( get_self(), evo_symbol.code().raw() );
const auto& token = statstable.find( evo_symbol.code().raw() );
check ( token != statstable.end(), "token symbol does not exist" );
auto pool1 = token->pool1;
auto pool2 = token->pool2;
placeindex(user, evo_symbol, pool1, pool2);
}

void evolutiondex::placeindex(name user, symbol evo_symbol,
extended_asset pool1, extended_asset pool2 ) {
auto id_256 = make256key(pool1.contract.value, pool1.quantity.symbol.raw(),
pool2.contract.value, pool2.quantity.symbol.raw());
evoindexes indextable( get_self(), get_self().value );
auto index = indextable.get_index<"extended"_n>();
const auto& info = index.find( id_256 );
check( info == index.end(), "the pool is already indexed");
indextable.emplace( user, [&]( auto& a ){
a.evo_symbol = evo_symbol;
a.id_256 = id_256;
});
}

void evolutiondex::changefee(symbol_code pair_token, int newfee) {
check( (0 <= newfee) && (newfee <= 500), "new fee out of reasonable range");
stats statstable( get_self(), pair_token.raw() );
const auto& token = statstable.find( pair_token.raw() );
check ( token != statstable.end(), "pair token does not exist" );
check( (token->fee_contract) != ""_n, "this pair token has fixed fee parameter" );
require_auth(token->fee_contract);
statstable.modify( token, same_payer, [&]( auto& a ) {
a.fee = newfee;
Expand All @@ -244,6 +270,13 @@ uint128_t evolutiondex::make128key(uint64_t a, uint64_t b) {
return (aa << 64) + bb;
}

checksum256 evolutiondex::make256key(uint64_t a, uint64_t b, uint64_t c, uint64_t d) {
if (make128key(a,b) < make128key(c,d))
return checksum256::make_from_word_sequence<uint64_t>(a,b,c,d);
else
return checksum256::make_from_word_sequence<uint64_t>(c,d,a,b);
}

void evolutiondex::add_signed_ext_balance( const name& user, const extended_asset& to_add )
{
check( to_add.quantity.is_valid(), "invalid asset" );
Expand Down
22 changes: 18 additions & 4 deletions evolutiondex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ namespace evolution {
public:
const int64_t MAX = eosio::asset::max_amount;
const int64_t INIT_MAX = 1000000000000000; // 10^15
const int ADD_LIQUIDITY_FEE = 1;
const int DEFAULT_FEE = 10;

using contract::contract;
[[eosio::action]] void inittoken(name user, symbol new_symbol,
Expand All @@ -33,7 +35,8 @@ namespace evolution {
const asset& quantity, const string& memo );
[[eosio::action]] void open( const name& owner, const symbol& symbol, const name& ram_payer );
[[eosio::action]] void close( const name& owner, const symbol& symbol );

[[eosio::action]] void indexpair(name user, symbol evo_symbol); // This action is only temporarily useful

private:

struct [[eosio::table]] account {
Expand All @@ -49,8 +52,6 @@ namespace evolution {
make128key(balance.contract.value, balance.quantity.symbol.raw() ); }
};

static uint128_t make128key(uint64_t a, uint64_t b);

struct [[eosio::table]] currency_stats {
asset supply;
asset max_supply;
Expand All @@ -62,19 +63,32 @@ namespace evolution {
uint64_t primary_key()const { return supply.symbol.code().raw(); }
};

struct [[eosio::table]] index_struct{
symbol evo_symbol;
checksum256 id_256;
uint64_t primary_key()const { return evo_symbol.code().raw(); }
checksum256 secondary_key()const { return id_256; }
};

typedef eosio::multi_index< "evodexacnts"_n, evodexaccount,
indexed_by<"extended"_n, const_mem_fun<evodexaccount, uint128_t,
&evodexaccount::secondary_key>> > evodexacnts;
typedef eosio::multi_index< "stat"_n, currency_stats > stats;
typedef eosio::multi_index< "evoindex"_n, index_struct,
indexed_by<"extended"_n, const_mem_fun<index_struct, checksum256,
&index_struct::secondary_key>> > evoindexes;
typedef eosio::multi_index< "accounts"_n, account > accounts;

static uint128_t make128key(uint64_t a, uint64_t b);
static checksum256 make256key(uint64_t a, uint64_t b, uint64_t c, uint64_t d);

void add_signed_ext_balance( const name& owner, const extended_asset& value );
void add_signed_liq(name user, asset to_buy, bool is_buying, asset max_asset1, asset max_asset2);
void memoexchange(name user, extended_asset ext_asset_in, string_view details);
extended_asset process_exch(symbol_code evo_token, extended_asset paying, asset min_expected);
int64_t compute(int64_t x, int64_t y, int64_t z, int fee);
asset string_to_asset(string input);

void placeindex(name user, symbol evo_symbol, extended_asset pool1, extended_asset pool2 );
void add_balance( const name& owner, const asset& value, const name& ram_payer );
void sub_balance( const name& owner, const asset& value );
};
Expand Down

0 comments on commit 0a3b05c

Please sign in to comment.