Skip to content

Commit 10298ca

Browse files
committed
Test case reproduces #338 #343 #453 #606 #625 #649
1 parent a9cb440 commit 10298ca

File tree

1 file changed

+116
-10
lines changed

1 file changed

+116
-10
lines changed

tests/tests/market_tests.cpp

+116-10
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,28 @@ using namespace graphene::wallet;
3939
BOOST_FIXTURE_TEST_SUITE(market_tests, database_fixture)
4040

4141
/***
42-
* Reproduce bitshares-core issue #338
42+
* Reproduce bitshares-core issue #338 #343 #453 #606 #625 #649
4343
*/
44-
BOOST_AUTO_TEST_CASE(issue_338)
44+
BOOST_AUTO_TEST_CASE(issue_338_etc)
4545
{ try {
4646
generate_blocks(HARDFORK_436_TIME);
4747
generate_block();
4848

4949
set_expiration( db, trx );
5050

51-
ACTORS((buyer)(seller)(borrower)(feedproducer));
51+
ACTORS((buyer)(seller)(borrower)(borrower2)(borrower3)(feedproducer));
5252

5353
const auto& bitusd = create_bitasset("USDBIT", feedproducer_id);
5454
const auto& core = asset_id_type()(db);
55+
asset_id_type usd_id = bitusd.id;
56+
asset_id_type core_id = core.id;
5557

5658
int64_t init_balance(1000000);
5759

5860
transfer(committee_account, buyer_id, asset(init_balance));
5961
transfer(committee_account, borrower_id, asset(init_balance));
62+
transfer(committee_account, borrower2_id, asset(init_balance));
63+
transfer(committee_account, borrower3_id, asset(init_balance));
6064
update_feed_producers( bitusd, {feedproducer.id} );
6165

6266
price_feed current_feed;
@@ -66,6 +70,13 @@ BOOST_AUTO_TEST_CASE(issue_338)
6670
publish_feed( bitusd, feedproducer, current_feed );
6771
// start out with 300% collateral, call price is 15/1.75 CORE/USD = 60/7
6872
const call_order_object& call = *borrow( borrower, bitusd.amount(1000), asset(15000));
73+
call_order_id_type call_id = call.id;
74+
// create another position with 310% collateral, call price is 15.5/1.75 CORE/USD = 63/7
75+
const call_order_object& call2 = *borrow( borrower2, bitusd.amount(1000), asset(15500));
76+
call_order_id_type call2_id = call2.id;
77+
// create yet another position with 320% collateral, call price is 16/1.75 CORE/USD = 64/7
78+
const call_order_object& call3 = *borrow( borrower3, bitusd.amount(1000), asset(16000));
79+
call_order_id_type call3_id = call3.id;
6980
transfer(borrower, seller, bitusd.amount(1000));
7081

7182
BOOST_CHECK_EQUAL( 1000, call.debt.value );
@@ -78,48 +89,143 @@ BOOST_AUTO_TEST_CASE(issue_338)
7889
publish_feed( bitusd, feedproducer, current_feed );
7990
// settlement price = 1/10, mssp = 1/11
8091

81-
// This order slightly below the call price will not be matched
92+
// This order slightly below the call price will not be matched #606
8293
limit_order_id_type sell_low = create_sell_order(seller, bitusd.amount(7), core.amount(59))->id;
8394
// This order above the MSSP will not be matched
8495
limit_order_id_type sell_high = create_sell_order(seller, bitusd.amount(7), core.amount(78))->id;
85-
// This would match but is blocked by sell_low?!
96+
// This would match but is blocked by sell_low?! #606
8697
limit_order_id_type sell_med = create_sell_order(seller, bitusd.amount(7), core.amount(60))->id;
8798

8899
cancel_limit_order( sell_med(db) );
89100
cancel_limit_order( sell_high(db) );
90101
cancel_limit_order( sell_low(db) );
91102

92103
// current implementation: an incoming limit order will be filled at the
93-
// requested price
104+
// requested price #338
94105
BOOST_CHECK( !create_sell_order(seller, bitusd.amount(7), core.amount(60)) );
95106
BOOST_CHECK_EQUAL( 993, get_balance(seller, bitusd) );
96107
BOOST_CHECK_EQUAL( 60, get_balance(seller, core) );
97108
BOOST_CHECK_EQUAL( 993, call.debt.value );
98109
BOOST_CHECK_EQUAL( 14940, call.collateral.value );
99110

100-
auto buy_low = create_sell_order(buyer, asset(90), bitusd.amount(10))->id;
111+
limit_order_id_type buy_low = create_sell_order(buyer, asset(90), bitusd.amount(10))->id;
101112
// margin call takes precedence
102113
BOOST_CHECK( !create_sell_order(seller, bitusd.amount(7), core.amount(60)) );
103114
BOOST_CHECK_EQUAL( 986, get_balance(seller, bitusd) );
104115
BOOST_CHECK_EQUAL( 120, get_balance(seller, core) );
105116
BOOST_CHECK_EQUAL( 986, call.debt.value );
106117
BOOST_CHECK_EQUAL( 14880, call.collateral.value );
107118

108-
auto buy_med = create_sell_order(buyer, asset(105), bitusd.amount(10))->id;
119+
limit_order_id_type buy_med = create_sell_order(buyer, asset(105), bitusd.amount(10))->id;
109120
// margin call takes precedence
110121
BOOST_CHECK( !create_sell_order(seller, bitusd.amount(7), core.amount(70)) );
111122
BOOST_CHECK_EQUAL( 979, get_balance(seller, bitusd) );
112123
BOOST_CHECK_EQUAL( 190, get_balance(seller, core) );
113124
BOOST_CHECK_EQUAL( 979, call.debt.value );
114125
BOOST_CHECK_EQUAL( 14810, call.collateral.value );
115126

116-
auto buy_high = create_sell_order(buyer, asset(115), bitusd.amount(10))->id;
117-
// margin call still has precedence (!))
127+
limit_order_id_type buy_high = create_sell_order(buyer, asset(115), bitusd.amount(10))->id;
128+
// margin call still has precedence (!) #625
118129
BOOST_CHECK( !create_sell_order(seller, bitusd.amount(7), core.amount(77)) );
119130
BOOST_CHECK_EQUAL( 972, get_balance(seller, bitusd) );
120131
BOOST_CHECK_EQUAL( 267, get_balance(seller, core) );
121132
BOOST_CHECK_EQUAL( 972, call.debt.value );
122133
BOOST_CHECK_EQUAL( 14733, call.collateral.value );
134+
135+
cancel_limit_order( buy_high(db) );
136+
cancel_limit_order( buy_med(db) );
137+
cancel_limit_order( buy_low(db) );
138+
139+
// call with more usd
140+
BOOST_CHECK( !create_sell_order(seller, bitusd.amount(700), core.amount(7700)) );
141+
BOOST_CHECK_EQUAL( 272, get_balance(seller, bitusd) );
142+
BOOST_CHECK_EQUAL( 7967, get_balance(seller, core) );
143+
BOOST_CHECK_EQUAL( 272, call.debt.value );
144+
BOOST_CHECK_EQUAL( 7033, call.collateral.value );
145+
146+
// at this moment, collateralization of call is 7033 / 272 = 25.8
147+
// collateralization of call2 is 15500 / 1000 = 15.5
148+
// collateralization of call3 is 16000 / 1000 = 16
149+
150+
// call more, still matches with the first call order #343
151+
BOOST_CHECK( !create_sell_order(seller, bitusd.amount(10), core.amount(110)) );
152+
BOOST_CHECK_EQUAL( 262, get_balance(seller, bitusd) );
153+
BOOST_CHECK_EQUAL( 8077, get_balance(seller, core) );
154+
BOOST_CHECK_EQUAL( 262, call.debt.value );
155+
BOOST_CHECK_EQUAL( 6923, call.collateral.value );
156+
157+
// at this moment, collateralization of call is 6923 / 262 = 26.4
158+
// collateralization of call2 is 15500 / 1000 = 15.5
159+
// collateralization of call3 is 16000 / 1000 = 16
160+
161+
// force settle
162+
force_settle( seller, bitusd.amount(10) );
163+
BOOST_CHECK_EQUAL( 252, get_balance(seller, bitusd) );
164+
BOOST_CHECK_EQUAL( 8077, get_balance(seller, core) );
165+
BOOST_CHECK_EQUAL( 262, call.debt.value );
166+
BOOST_CHECK_EQUAL( 6923, call.collateral.value );
167+
168+
// generate blocks to let the settle order execute
169+
generate_blocks( HARDFORK_436_TIME + fc::days(2) );
170+
// call2 get settled #343
171+
BOOST_CHECK_EQUAL( 252, get_balance(seller_id, usd_id) );
172+
BOOST_CHECK_EQUAL( 8177, get_balance(seller_id, core_id) );
173+
BOOST_CHECK_EQUAL( 262, call_id(db).debt.value );
174+
BOOST_CHECK_EQUAL( 6923, call_id(db).collateral.value );
175+
BOOST_CHECK_EQUAL( 990, call2_id(db).debt.value );
176+
BOOST_CHECK_EQUAL( 15400, call2_id(db).collateral.value );
177+
178+
set_expiration( db, trx );
179+
update_feed_producers( usd_id(db), {feedproducer_id} );
180+
181+
// at this moment, collateralization of call is 8177 / 252 = 32.4
182+
// collateralization of call2 is 15400 / 990 = 15.5
183+
// collateralization of call3 is 16000 / 1000 = 16
184+
185+
// adjust price feed to get call2 into black swan territory, but not the first call order
186+
current_feed.settlement_price = asset(1, usd_id) / asset(20, core_id);
187+
publish_feed( usd_id(db), feedproducer_id(db), current_feed );
188+
// settlement price = 1/20, mssp = 1/22
189+
190+
// black swan event doesn't occur #649
191+
BOOST_CHECK( !usd_id(db).bitasset_data(db).has_settlement() );
192+
193+
// generate a block
194+
generate_block();
195+
196+
set_expiration( db, trx );
197+
update_feed_producers( usd_id(db), {feedproducer_id} );
198+
199+
// adjust price feed back
200+
current_feed.settlement_price = asset(1, usd_id) / asset(10, core_id);
201+
publish_feed( usd_id(db), feedproducer_id(db), current_feed );
202+
// settlement price = 1/10, mssp = 1/11
203+
204+
transfer(borrower2_id, seller_id, asset(1000, usd_id));
205+
transfer(borrower3_id, seller_id, asset(1000, usd_id));
206+
207+
// Re-create sell_low, slightly below the call price, will not be matched, will expire soon
208+
sell_low = create_sell_order(seller_id(db), asset(7, usd_id), asset(59), db.head_block_time() )->id;
209+
// This would match but is blocked by sell_low, it has an amount same as call's debt which will be full filled later
210+
sell_med = create_sell_order(seller_id(db), asset(262, usd_id), asset(2620))->id; // 1/10
211+
// Another big order above sell_med, blocked
212+
limit_order_id_type sell_med2 = create_sell_order(seller_id(db), asset(1200, usd_id), asset(12120))->id; // 1/10.1
213+
// Another small order above sell_med2, blocked
214+
limit_order_id_type sell_med3 = create_sell_order(seller_id(db), asset(120, usd_id), asset(1224))->id; // 1/10.2
215+
216+
// generate a block, sell_low will expire
217+
generate_block();
218+
BOOST_CHECK( db.find<limit_order_object>( sell_low ) == nullptr );
219+
220+
// #453 multiple order matching issue occurs
221+
BOOST_CHECK( db.find<limit_order_object>( sell_med ) == nullptr ); // sell_med get filled
222+
BOOST_CHECK( db.find<limit_order_object>( sell_med2 ) != nullptr ); // sell_med2 is still there
223+
BOOST_CHECK( db.find<limit_order_object>( sell_med3 ) == nullptr ); // sell_med3 get filled
224+
BOOST_CHECK( db.find<call_order_object>( call_id ) == nullptr ); // the first call order get filled
225+
BOOST_CHECK( db.find<call_order_object>( call2_id ) == nullptr ); // the second call order get filled
226+
BOOST_CHECK( db.find<call_order_object>( call3_id ) != nullptr ); // the third call order is still there
227+
228+
123229
} FC_LOG_AND_RETHROW() }
124230

125231
/***

0 commit comments

Comments
 (0)