-
Notifications
You must be signed in to change notification settings - Fork 43
/
exchange_state.cpp
83 lines (63 loc) · 2.49 KB
/
exchange_state.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "exchange_state.hpp"
namespace eosiosystem {
asset exchange_state::convert_to_exchange( connector& c, asset in ) {
real_type R(supply.amount);
real_type C(c.balance.amount+in.amount);
real_type F(c.weight);
real_type T(in.amount);
real_type ONE(1.0);
real_type E = -R * (ONE - std::pow( ONE + T / C, F) );
int64_t issued = int64_t(E);
supply.amount += issued;
c.balance.amount += in.amount;
return asset( issued, supply.symbol );
}
asset exchange_state::convert_from_exchange( connector& c, asset in ) {
check( in.symbol== supply.symbol, "unexpected asset symbol input" );
real_type R(supply.amount - in.amount);
real_type C(c.balance.amount);
real_type F(1.0/c.weight);
real_type E(in.amount);
real_type ONE(1.0);
// potentially more accurate:
// The functions std::expm1 and std::log1p are useful for financial calculations, for example,
// when calculating small daily interest rates: (1+x)n
// -1 can be expressed as std::expm1(n * std::log1p(x)).
// real_type T = C * std::expm1( F * std::log1p(E/R) );
real_type T = C * (std::pow( ONE + E/R, F) - ONE);
int64_t out = int64_t(T);
supply.amount -= in.amount;
c.balance.amount -= out;
return asset( out, c.balance.symbol );
}
asset exchange_state::convert( asset from, const symbol& to ) {
auto sell_symbol = from.symbol;
auto ex_symbol = supply.symbol;
auto base_symbol = base.balance.symbol;
auto quote_symbol = quote.balance.symbol;
//print( "From: ", from, " TO ", asset( 0,to), "\n" );
//print( "base: ", base_symbol, "\n" );
//print( "quote: ", quote_symbol, "\n" );
//print( "ex: ", supply.symbol, "\n" );
if( sell_symbol != ex_symbol ) {
if( sell_symbol == base_symbol ) {
from = convert_to_exchange( base, from );
} else if( sell_symbol == quote_symbol ) {
from = convert_to_exchange( quote, from );
} else {
check( false, "invalid sell" );
}
} else {
if( to == base_symbol ) {
from = convert_from_exchange( base, from );
} else if( to == quote_symbol ) {
from = convert_from_exchange( quote, from );
} else {
check( false, "invalid conversion" );
}
}
if( to != from.symbol )
return convert( from, to );
return from;
}
} /// namespace eosiosystem