1
use crate::{
2
    admin::{delete_route, set_route},
3
    state::{read_swap_route, store_swap_route, CONFIG},
4
    testing::test_utils::{mock_deps_eth_inj, MultiplierQueryBehavior, TEST_CONTRACT_ADDR, TEST_USER_ADDR},
5
    types::{Config, SwapRoute},
6
};
7
use cosmwasm_std::Addr;
8
use injective_cosmwasm::{inj_mock_deps, MarketId, OwnedDepsExt, TEST_MARKET_ID_1, TEST_MARKET_ID_2, TEST_MARKET_ID_3};
9

            
10
#[test]
11
2
fn it_can_store_and_read_swap_route() {
12
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
13
2
    let source_denom = "eth";
14
2
    let target_denom = "inj";
15
2

            
16
2
    let route = SwapRoute {
17
2
        steps: vec![MarketId::unchecked(TEST_MARKET_ID_1), MarketId::unchecked(TEST_MARKET_ID_2)],
18
2
        source_denom: source_denom.to_string(),
19
2
        target_denom: target_denom.to_string(),
20
2
    };
21
2

            
22
2
    store_swap_route(deps.as_mut().storage, &route).unwrap();
23
2

            
24
2
    let stored_route = read_swap_route(&deps.storage, source_denom, target_denom).unwrap();
25
2
    assert_eq!(stored_route, route, "stored route was not read correctly");
26

            
27
    // Read with reversed denoms
28
2
    let stored_route_reversed = read_swap_route(&deps.storage, target_denom, source_denom).unwrap();
29
2
    assert_eq!(stored_route_reversed, route);
30

            
31
2
    let non_existent_route = read_swap_route(&deps.storage, "nonexistent", "route");
32
2
    assert!(non_existent_route.is_err(), "non-existent route was read");
33
2
}
34

            
35
#[test]
36
2
fn it_can_update_and_read_swap_route() {
37
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
38
2
    let source_denom = "eth";
39
2
    let target_denom = "usdt";
40
2

            
41
2
    let route = SwapRoute {
42
2
        steps: vec![MarketId::unchecked(TEST_MARKET_ID_1)],
43
2
        source_denom: source_denom.to_string(),
44
2
        target_denom: target_denom.to_string(),
45
2
    };
46
2

            
47
2
    store_swap_route(deps.as_mut().storage, &route).unwrap();
48
2

            
49
2
    let mut stored_route = read_swap_route(&deps.storage, source_denom, target_denom).unwrap();
50
2
    assert_eq!(stored_route, route, "stored route was not read correctly");
51

            
52
2
    let new_target_denom = "inj";
53
2

            
54
2
    let updated_route = SwapRoute {
55
2
        steps: vec![MarketId::unchecked(TEST_MARKET_ID_1), MarketId::unchecked(TEST_MARKET_ID_2)],
56
2
        source_denom: source_denom.to_string(),
57
2
        target_denom: new_target_denom.to_string(),
58
2
    };
59
2

            
60
2
    store_swap_route(deps.as_mut().storage, &updated_route).unwrap();
61
2

            
62
2
    stored_route = read_swap_route(&deps.storage, source_denom, new_target_denom).unwrap();
63
2
    assert_eq!(stored_route, updated_route, "stored route was not updated");
64
2
}
65

            
66
#[test]
67
2
fn owner_can_set_valid_route() {
68
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
69
2
    let source_denom = "eth".to_string();
70
2
    let target_denom = "inj".to_string();
71
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_1), MarketId::unchecked(TEST_MARKET_ID_2)];
72
2

            
73
2
    let config = Config {
74
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
75
2
        admin: Addr::unchecked(TEST_USER_ADDR),
76
2
    };
77
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
78
2

            
79
2
    let result = set_route(
80
2
        deps.as_mut(),
81
2
        &Addr::unchecked(TEST_USER_ADDR),
82
2
        source_denom.clone(),
83
2
        target_denom.clone(),
84
2
        route.clone(),
85
2
    );
86
2

            
87
2
    assert!(result.is_ok(), "result was not ok");
88

            
89
2
    let response = result.unwrap();
90
2
    assert_eq!(response.attributes[0].key, "method", "method attribute was not set");
91
2
    assert_eq!(response.attributes[0].value, "set_route", "method attribute was not set");
92

            
93
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom).unwrap();
94
2
    assert_eq!(stored_route.steps, route, "route was not set correctly");
95
2
    assert_eq!(stored_route.source_denom, source_denom, "route was not set correctly");
96
2
    assert_eq!(stored_route.target_denom, target_denom, "route was not set correctly");
97
2
}
98

            
99
#[test]
100
2
fn owner_cannot_set_route_for_markets_using_target_denom_not_found_on_target_market() {
101
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
102
2
    let source_denom = "eth".to_string();
103
2
    let target_denom = "atom".to_string();
104
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_1), MarketId::unchecked(TEST_MARKET_ID_2)];
105
2

            
106
2
    let config = Config {
107
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
108
2
        admin: Addr::unchecked(TEST_USER_ADDR),
109
2
    };
110
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
111
2

            
112
2
    let result = set_route(
113
2
        deps.as_mut(),
114
2
        &Addr::unchecked(TEST_USER_ADDR),
115
2
        source_denom.clone(),
116
2
        target_denom.clone(),
117
2
        route,
118
2
    );
119
2

            
120
2
    assert!(result.is_err(), "result was ok");
121
2
    assert!(
122
2
        result.unwrap_err().to_string().contains("Target denom not found in last market"),
123
        "wrong error message"
124
    );
125

            
126
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom);
127
2
    assert!(stored_route.is_err(), "route was set");
128
2
}
129

            
130
#[test]
131
2
fn owner_cannot_set_route_for_markets_using_source_denom_not_present_on_source_market() {
132
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
133
2
    let source_denom = "atom".to_string();
134
2
    let target_denom = "eth".to_string();
135
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_1), MarketId::unchecked(TEST_MARKET_ID_2)];
136
2

            
137
2
    let config = Config {
138
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
139
2
        admin: Addr::unchecked(TEST_USER_ADDR),
140
2
    };
141
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
142
2

            
143
2
    let result = set_route(
144
2
        deps.as_mut(),
145
2
        &Addr::unchecked(TEST_USER_ADDR),
146
2
        source_denom.clone(),
147
2
        target_denom.clone(),
148
2
        route,
149
2
    );
150
2

            
151
2
    assert!(result.is_err(), "result was ok");
152
2
    assert!(
153
2
        result.unwrap_err().to_string().contains("Source denom not found in first market"),
154
        "wrong error message"
155
    );
156

            
157
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom);
158
2
    assert!(stored_route.is_err(), "route was set");
159
2
}
160

            
161
#[test]
162
2
fn owner_can_set_route_single_step_route() {
163
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
164
2
    let source_denom = "eth".to_string();
165
2
    let target_denom = "usdt".to_string();
166
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_1)];
167
2

            
168
2
    let config = Config {
169
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
170
2
        admin: Addr::unchecked(TEST_USER_ADDR),
171
2
    };
172
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
173
2

            
174
2
    let result = set_route(
175
2
        deps.as_mut(),
176
2
        &Addr::unchecked(TEST_USER_ADDR),
177
2
        source_denom.clone(),
178
2
        target_denom.clone(),
179
2
        route.clone(),
180
2
    );
181
2

            
182
2
    assert!(result.is_ok(), "result was not ok");
183

            
184
2
    let response = result.unwrap();
185
2
    assert_eq!(response.attributes[0].key, "method", "method attribute was not set");
186
2
    assert_eq!(response.attributes[0].value, "set_route", "method attribute was not set");
187

            
188
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom).unwrap();
189
2
    assert_eq!(stored_route.steps, route, "route was not stored correctly");
190
2
    assert_eq!(stored_route.source_denom, source_denom, "source_denom was not stored correctly");
191
2
    assert_eq!(stored_route.target_denom, target_denom, "target_denom was not stored correctly");
192
2
}
193

            
194
#[test]
195
2
fn owner_can_set_route_single_step_route_with_reverted_denoms() {
196
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
197
2
    let source_denom = "usdt".to_string();
198
2
    let target_denom = "eth".to_string();
199
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_1)];
200
2

            
201
2
    let config = Config {
202
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
203
2
        admin: Addr::unchecked(TEST_USER_ADDR),
204
2
    };
205
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
206
2

            
207
2
    let result = set_route(
208
2
        deps.as_mut(),
209
2
        &Addr::unchecked(TEST_USER_ADDR),
210
2
        source_denom.clone(),
211
2
        target_denom.clone(),
212
2
        route.clone(),
213
2
    );
214
2

            
215
2
    assert!(result.is_ok(), "result was not ok");
216

            
217
2
    let response = result.unwrap();
218
2
    assert_eq!(response.attributes[0].key, "method", "method attribute was not set");
219
2
    assert_eq!(response.attributes[0].value, "set_route", "method attribute was not set");
220

            
221
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom).unwrap();
222
2
    assert_eq!(stored_route.steps, route, "route was not stored correctly");
223
2
    assert_eq!(stored_route.source_denom, source_denom, "source_denom was not stored correctly");
224
2
    assert_eq!(stored_route.target_denom, target_denom, "target_denom was not stored correctly");
225
2
}
226

            
227
#[test]
228
2
fn it_returns_error_when_setting_route_for_the_same_denom_as_target_and_source() {
229
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
230
2
    let source_denom = "eth".to_string();
231
2
    let target_denom = "eth".to_string();
232
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_1), MarketId::unchecked(TEST_MARKET_ID_2)];
233
2

            
234
2
    let config = Config {
235
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
236
2
        admin: Addr::unchecked(TEST_USER_ADDR),
237
2
    };
238
2

            
239
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
240
2

            
241
2
    let result = set_route(
242
2
        deps.as_mut(),
243
2
        &Addr::unchecked(TEST_USER_ADDR),
244
2
        source_denom.clone(),
245
2
        target_denom.clone(),
246
2
        route,
247
2
    );
248
2

            
249
2
    assert!(result.is_err(), "Could set a route with the same denom being source and target!");
250
2
    assert!(
251
2
        result
252
2
            .unwrap_err()
253
2
            .to_string()
254
2
            .contains("Cannot set a route with the same denom being source and target"),
255
        "wrong error message"
256
    );
257

            
258
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom);
259
2
    assert!(stored_route.is_err(), "Could read a route with the same denom being source and target!");
260
2
}
261

            
262
#[test]
263
2
fn it_returns_error_when_setting_route_with_nonexistent_market_id() {
264
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
265
2
    let source_denom = "eth".to_string();
266
2
    let target_denom = "usdt".to_string();
267
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_3)];
268
2

            
269
2
    let config = Config {
270
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
271
2
        admin: Addr::unchecked(TEST_USER_ADDR),
272
2
    };
273
2

            
274
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
275
2

            
276
2
    let result = set_route(
277
2
        deps.as_mut(),
278
2
        &Addr::unchecked(TEST_USER_ADDR),
279
2
        source_denom.clone(),
280
2
        target_denom.clone(),
281
2
        route,
282
2
    );
283
2

            
284
2
    assert!(result.is_err(), "Could set a route for non-existent market");
285
2
    let err_result = result.unwrap_err();
286
2

            
287
2
    assert!(
288
2
        err_result.to_string().contains(&format!("Market {TEST_MARKET_ID_3} not found")),
289
        "wrong error message"
290
    );
291

            
292
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom);
293
2
    assert!(stored_route.is_err(), "Could read a route for non-existent market");
294
2
}
295

            
296
#[test]
297
2
fn it_returns_error_when_setting_route_with_no_market_ids() {
298
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
299
2
    let source_denom = "eth".to_string();
300
2
    let target_denom = "usdt".to_string();
301
2
    let route = vec![];
302
2

            
303
2
    let config = Config {
304
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
305
2
        admin: Addr::unchecked(TEST_USER_ADDR),
306
2
    };
307
2

            
308
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
309
2

            
310
2
    let result = set_route(
311
2
        deps.as_mut(),
312
2
        &Addr::unchecked(TEST_USER_ADDR),
313
2
        source_denom.clone(),
314
2
        target_denom.clone(),
315
2
        route,
316
2
    );
317
2

            
318
2
    assert!(result.is_err(), "Could set a route without any steps");
319
2
    assert!(
320
2
        result.unwrap_err().to_string().contains("Route must have at least one step"),
321
        "wrong error message"
322
    );
323

            
324
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom);
325
2
    assert!(stored_route.is_err(), "Could read a route without any steps");
326
2
}
327

            
328
#[test]
329
2
fn it_returns_error_when_setting_route_with_duplicated_market_ids() {
330
3
    let mut deps = inj_mock_deps(|_| {});
331
2
    let source_denom = "eth".to_string();
332
2
    let target_denom = "usdt".to_string();
333
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_1), MarketId::unchecked(TEST_MARKET_ID_1)];
334
2

            
335
2
    let config = Config {
336
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
337
2
        admin: Addr::unchecked(TEST_USER_ADDR),
338
2
    };
339
2

            
340
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
341
2

            
342
2
    let result = set_route(
343
2
        deps.as_mut(),
344
2
        &Addr::unchecked(TEST_USER_ADDR),
345
2
        source_denom.clone(),
346
2
        target_denom.clone(),
347
2
        route,
348
2
    );
349
2

            
350
2
    assert!(result.is_err(), "Could set a route that begins and ends with the same market");
351
2
    assert!(
352
2
        result.unwrap_err().to_string().contains("Route cannot have duplicate steps"),
353
        "wrong error message"
354
    );
355

            
356
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom);
357
2
    assert!(stored_route.is_err(), "Could read a route that begins and ends with the same market");
358
2
}
359

            
360
#[test]
361
2
fn it_returns_error_if_non_admin_tries_to_set_route() {
362
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
363
2
    let source_denom = "eth".to_string();
364
2
    let target_denom = "inj".to_string();
365
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_1), MarketId::unchecked(TEST_MARKET_ID_2)];
366
2

            
367
2
    let config = Config {
368
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
369
2
        admin: Addr::unchecked(TEST_USER_ADDR),
370
2
    };
371
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
372
2

            
373
2
    let result = set_route(
374
2
        deps.as_mut(),
375
2
        &Addr::unchecked(TEST_CONTRACT_ADDR),
376
2
        source_denom.clone(),
377
2
        target_denom.clone(),
378
2
        route,
379
2
    );
380
2

            
381
2
    assert!(result.is_err(), "expected error");
382
2
    assert!(result.unwrap_err().to_string().contains("Unauthorized"), "wrong error message");
383

            
384
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom).unwrap_err();
385
2
    assert!(
386
2
        stored_route.to_string().contains("No swap route not found from eth to inj"),
387
        "wrong error message"
388
    );
389
2
}
390

            
391
#[test]
392
2
fn it_allows_admint_to_delete_existing_route() {
393
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
394
2
    let source_denom = "eth".to_string();
395
2
    let target_denom = "inj".to_string();
396
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_1), MarketId::unchecked(TEST_MARKET_ID_2)];
397
2

            
398
2
    let config = Config {
399
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
400
2
        admin: Addr::unchecked(TEST_USER_ADDR),
401
2
    };
402
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
403
2

            
404
2
    let set_result = set_route(
405
2
        deps.as_mut(),
406
2
        &Addr::unchecked(TEST_USER_ADDR),
407
2
        source_denom.clone(),
408
2
        target_denom.clone(),
409
2
        route,
410
2
    );
411
2

            
412
2
    assert!(set_result.is_ok(), "expected success on set");
413

            
414
2
    let delete_result = delete_route(
415
2
        deps.as_mut(),
416
2
        &Addr::unchecked(TEST_USER_ADDR),
417
2
        source_denom.clone(),
418
2
        target_denom.clone(),
419
2
    );
420
2

            
421
2
    assert!(delete_result.is_ok(), "expected success on delete");
422

            
423
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom).unwrap_err();
424
2
    assert!(
425
2
        stored_route.to_string().contains("No swap route not found from eth to inj"),
426
        "route was not deleted and could be read"
427
    );
428
2
}
429

            
430
#[test]
431
2
fn it_doesnt_fail_if_admin_deletes_non_existent_route() {
432
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
433
2
    let source_denom = "eth".to_string();
434
2
    let target_denom = "inj".to_string();
435
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_1), MarketId::unchecked(TEST_MARKET_ID_2)];
436
2

            
437
2
    let config = Config {
438
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
439
2
        admin: Addr::unchecked(TEST_USER_ADDR),
440
2
    };
441
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
442
2

            
443
2
    let set_result = set_route(
444
2
        deps.as_mut(),
445
2
        &Addr::unchecked(TEST_USER_ADDR),
446
2
        source_denom.clone(),
447
2
        target_denom.clone(),
448
2
        route,
449
2
    );
450
2

            
451
2
    assert!(set_result.is_ok(), "expected success on set");
452

            
453
2
    let delete_result = delete_route(
454
2
        deps.as_mut(),
455
2
        &Addr::unchecked(TEST_USER_ADDR),
456
2
        source_denom.clone(),
457
2
        "mietek".to_string(),
458
2
    );
459
2

            
460
2
    assert!(delete_result.is_ok(), "expected success on delete");
461

            
462
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom);
463
2
    assert!(stored_route.is_ok(), "route was deleted");
464
2
}
465

            
466
#[test]
467
2
fn it_returns_error_if_non_admin_tries_to_delete_route() {
468
2
    let mut deps = mock_deps_eth_inj(MultiplierQueryBehavior::Success);
469
2
    let source_denom = "eth".to_string();
470
2
    let target_denom = "inj".to_string();
471
2
    let route = vec![MarketId::unchecked(TEST_MARKET_ID_1), MarketId::unchecked(TEST_MARKET_ID_2)];
472
2

            
473
2
    let config = Config {
474
2
        fee_recipient: Addr::unchecked(TEST_USER_ADDR),
475
2
        admin: Addr::unchecked(TEST_USER_ADDR),
476
2
    };
477
2
    CONFIG.save(deps.as_mut_deps().storage, &config).expect("could not save config");
478
2

            
479
2
    let set_result = set_route(
480
2
        deps.as_mut(),
481
2
        &Addr::unchecked(TEST_USER_ADDR),
482
2
        source_denom.clone(),
483
2
        target_denom.clone(),
484
2
        route,
485
2
    );
486
2

            
487
2
    assert!(set_result.is_ok(), "expected success on set");
488

            
489
2
    let delete_result = delete_route(
490
2
        deps.as_mut(),
491
2
        &Addr::unchecked(TEST_CONTRACT_ADDR),
492
2
        source_denom.clone(),
493
2
        target_denom.clone(),
494
2
    );
495
2

            
496
2
    assert!(delete_result.is_err(), "expected error on delete");
497

            
498
2
    let stored_route = read_swap_route(&deps.storage, &source_denom, &target_denom);
499
2
    assert!(stored_route.is_ok(), "route was deleted");
500
2
}