Skip to content

Commit 86b1afc

Browse files
authored
test(interchain-token-service): add test for 3 chain cycle (#697)
1 parent fc6a657 commit 86b1afc

4 files changed

+437
-0
lines changed

contracts/interchain-token-service/tests/execute.rs

+306
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,312 @@ fn execute_message_interchain_transfer_should_scale_the_amount_when_source_decim
314314
);
315315
}
316316

317+
#[test]
318+
fn execute_message_interchain_transfer_should_scale_correctly_in_3_chain_cycle() {
319+
let TestMessage {
320+
source_its_contract,
321+
..
322+
} = TestMessage::dummy();
323+
let configs = vec![
324+
(
325+
"ethereum".parse().unwrap(),
326+
source_its_contract.clone(),
327+
Uint256::MAX.try_into().unwrap(),
328+
u8::MAX,
329+
),
330+
(
331+
"stellar".parse().unwrap(),
332+
source_its_contract.clone(),
333+
Uint256::from(u128::MAX).try_into().unwrap(),
334+
12,
335+
),
336+
(
337+
"sui".parse().unwrap(),
338+
source_its_contract.clone(),
339+
Uint256::from(u64::MAX).try_into().unwrap(),
340+
6,
341+
),
342+
];
343+
344+
let (mut deps, TestMessage { router_message, .. }) =
345+
utils::setup_multiple_chains(configs.clone());
346+
let token_id = TokenId::new([1; 32]);
347+
let deploy_token = DeployInterchainToken {
348+
token_id,
349+
name: "Test".try_into().unwrap(),
350+
symbol: "TST".try_into().unwrap(),
351+
decimals: 18,
352+
minter: None,
353+
};
354+
let hub_message = HubMessage::SendToHub {
355+
destination_chain: configs[1].0.clone(),
356+
message: deploy_token.clone().into(),
357+
};
358+
assert_ok!(utils::execute_hub_message(
359+
deps.as_mut(),
360+
CrossChainId {
361+
source_chain: configs[0].0.clone(),
362+
message_id: router_message.cc_id.message_id.clone()
363+
},
364+
source_its_contract.clone(),
365+
hub_message,
366+
));
367+
368+
let hub_message = HubMessage::SendToHub {
369+
destination_chain: configs[2].0.clone(),
370+
message: deploy_token.clone().into(),
371+
};
372+
assert_ok!(utils::execute_hub_message(
373+
deps.as_mut(),
374+
CrossChainId {
375+
source_chain: configs[0].0.clone(),
376+
message_id: router_message.cc_id.message_id.clone()
377+
},
378+
source_its_contract.clone(),
379+
hub_message,
380+
));
381+
382+
let amount: nonempty::Uint256 = Uint256::from_u128(1000000000000000000u128)
383+
.try_into()
384+
.unwrap();
385+
386+
// send from chain 0 to chain 1
387+
let transfer = InterchainTransfer {
388+
token_id,
389+
source_address: HexBinary::from([1; 32]).try_into().unwrap(),
390+
destination_address: HexBinary::from([2; 32]).try_into().unwrap(),
391+
amount,
392+
data: None,
393+
};
394+
let hub_message = HubMessage::SendToHub {
395+
destination_chain: configs[1].0.clone(),
396+
message: transfer.into(),
397+
};
398+
399+
assert_ok!(utils::execute_hub_message(
400+
deps.as_mut(),
401+
CrossChainId {
402+
source_chain: configs[0].0.clone(),
403+
message_id: router_message.cc_id.message_id.clone()
404+
},
405+
source_its_contract.clone(),
406+
hub_message,
407+
));
408+
409+
let scaling_factor = Uint256::from_u128(10)
410+
.checked_pow(deploy_token.decimals.abs_diff(configs[1].3).into())
411+
.unwrap();
412+
let scaled_amount = amount.clone().checked_div(scaling_factor).unwrap();
413+
414+
// send back from destination to source
415+
let transfer = InterchainTransfer {
416+
token_id,
417+
source_address: HexBinary::from([2; 32]).try_into().unwrap(),
418+
destination_address: HexBinary::from([1; 32]).try_into().unwrap(),
419+
amount: scaled_amount.try_into().unwrap(),
420+
data: None,
421+
};
422+
423+
let hub_message = HubMessage::SendToHub {
424+
destination_chain: configs[2].0.clone(),
425+
message: transfer.into(),
426+
};
427+
428+
assert_ok!(utils::execute_hub_message(
429+
deps.as_mut(),
430+
CrossChainId {
431+
source_chain: configs[1].0.clone(),
432+
message_id: router_message.cc_id.message_id.clone()
433+
},
434+
source_its_contract.clone(),
435+
hub_message,
436+
));
437+
438+
let scaling_factor = Uint256::from_u128(10)
439+
.checked_pow(deploy_token.decimals.abs_diff(configs[2].3).into())
440+
.unwrap();
441+
let scaled_amount = amount.clone().checked_div(scaling_factor).unwrap();
442+
443+
// send back from destination to source
444+
let transfer = InterchainTransfer {
445+
token_id,
446+
source_address: HexBinary::from([2; 32]).try_into().unwrap(),
447+
destination_address: HexBinary::from([1; 32]).try_into().unwrap(),
448+
amount: scaled_amount.try_into().unwrap(),
449+
data: None,
450+
};
451+
452+
let hub_message = HubMessage::SendToHub {
453+
destination_chain: configs[0].0.clone(),
454+
message: transfer.into(),
455+
};
456+
457+
let response_to_destination = assert_ok!(utils::execute_hub_message(
458+
deps.as_mut(),
459+
CrossChainId {
460+
source_chain: configs[2].0.clone(),
461+
message_id: router_message.cc_id.message_id.clone()
462+
},
463+
source_its_contract,
464+
hub_message,
465+
));
466+
467+
goldie::assert_json!(response_to_destination);
468+
}
469+
470+
#[test]
471+
fn execute_message_interchain_transfer_should_scale_correctly_in_3_chain_cycle_with_dust() {
472+
let TestMessage {
473+
source_its_contract,
474+
..
475+
} = TestMessage::dummy();
476+
let configs = vec![
477+
(
478+
"ethereum".parse().unwrap(),
479+
source_its_contract.clone(),
480+
Uint256::MAX.try_into().unwrap(),
481+
u8::MAX,
482+
),
483+
(
484+
"stellar".parse().unwrap(),
485+
source_its_contract.clone(),
486+
Uint256::from(u128::MAX).try_into().unwrap(),
487+
12,
488+
),
489+
(
490+
"sui".parse().unwrap(),
491+
source_its_contract.clone(),
492+
Uint256::from(u64::MAX).try_into().unwrap(),
493+
6,
494+
),
495+
];
496+
497+
let (mut deps, TestMessage { router_message, .. }) =
498+
utils::setup_multiple_chains(configs.clone());
499+
let token_id = TokenId::new([1; 32]);
500+
let deploy_token = DeployInterchainToken {
501+
token_id,
502+
name: "Test".try_into().unwrap(),
503+
symbol: "TST".try_into().unwrap(),
504+
decimals: 18,
505+
minter: None,
506+
};
507+
let hub_message = HubMessage::SendToHub {
508+
destination_chain: configs[1].0.clone(),
509+
message: deploy_token.clone().into(),
510+
};
511+
assert_ok!(utils::execute_hub_message(
512+
deps.as_mut(),
513+
CrossChainId {
514+
source_chain: configs[0].0.clone(),
515+
message_id: router_message.cc_id.message_id.clone()
516+
},
517+
source_its_contract.clone(),
518+
hub_message,
519+
));
520+
521+
let hub_message = HubMessage::SendToHub {
522+
destination_chain: configs[2].0.clone(),
523+
message: deploy_token.clone().into(),
524+
};
525+
assert_ok!(utils::execute_hub_message(
526+
deps.as_mut(),
527+
CrossChainId {
528+
source_chain: configs[0].0.clone(),
529+
message_id: router_message.cc_id.message_id.clone()
530+
},
531+
source_its_contract.clone(),
532+
hub_message,
533+
));
534+
535+
let amount: nonempty::Uint256 = Uint256::from_u128(1000000000010000001u128)
536+
.try_into()
537+
.unwrap();
538+
539+
// send from chain 0 to chain 1
540+
let transfer = InterchainTransfer {
541+
token_id,
542+
source_address: HexBinary::from([1; 32]).try_into().unwrap(),
543+
destination_address: HexBinary::from([2; 32]).try_into().unwrap(),
544+
amount,
545+
data: None,
546+
};
547+
let hub_message = HubMessage::SendToHub {
548+
destination_chain: configs[1].0.clone(),
549+
message: transfer.into(),
550+
};
551+
552+
assert_ok!(utils::execute_hub_message(
553+
deps.as_mut(),
554+
CrossChainId {
555+
source_chain: configs[0].0.clone(),
556+
message_id: router_message.cc_id.message_id.clone()
557+
},
558+
source_its_contract.clone(),
559+
hub_message,
560+
));
561+
562+
let scaling_factor = Uint256::from_u128(10)
563+
.checked_pow(deploy_token.decimals.abs_diff(configs[1].3).into())
564+
.unwrap();
565+
let scaled_amount = amount.clone().checked_div(scaling_factor).unwrap();
566+
567+
// send back from destination to source
568+
let transfer = InterchainTransfer {
569+
token_id,
570+
source_address: HexBinary::from([2; 32]).try_into().unwrap(),
571+
destination_address: HexBinary::from([1; 32]).try_into().unwrap(),
572+
amount: scaled_amount.try_into().unwrap(),
573+
data: None,
574+
};
575+
576+
let hub_message = HubMessage::SendToHub {
577+
destination_chain: configs[2].0.clone(),
578+
message: transfer.into(),
579+
};
580+
581+
assert_ok!(utils::execute_hub_message(
582+
deps.as_mut(),
583+
CrossChainId {
584+
source_chain: configs[1].0.clone(),
585+
message_id: router_message.cc_id.message_id.clone()
586+
},
587+
source_its_contract.clone(),
588+
hub_message,
589+
));
590+
591+
let scaling_factor = Uint256::from_u128(10)
592+
.checked_pow(deploy_token.decimals.abs_diff(configs[2].3).into())
593+
.unwrap();
594+
let scaled_amount = amount.clone().checked_div(scaling_factor).unwrap();
595+
596+
// send back from destination to source
597+
let transfer = InterchainTransfer {
598+
token_id,
599+
source_address: HexBinary::from([2; 32]).try_into().unwrap(),
600+
destination_address: HexBinary::from([1; 32]).try_into().unwrap(),
601+
amount: scaled_amount.try_into().unwrap(),
602+
data: None,
603+
};
604+
605+
let hub_message = HubMessage::SendToHub {
606+
destination_chain: configs[0].0.clone(),
607+
message: transfer.into(),
608+
};
609+
610+
let response_to_destination = assert_ok!(utils::execute_hub_message(
611+
deps.as_mut(),
612+
CrossChainId {
613+
source_chain: configs[2].0.clone(),
614+
message_id: router_message.cc_id.message_id.clone()
615+
},
616+
source_its_contract,
617+
hub_message,
618+
));
619+
620+
goldie::assert_json!(response_to_destination);
621+
}
622+
317623
#[test]
318624
fn execute_message_deploy_interchain_token_should_translate_decimals_when_max_uints_are_different()
319625
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"messages": [
3+
{
4+
"id": 0,
5+
"msg": {
6+
"wasm": {
7+
"execute": {
8+
"contract_addr": "gateway",
9+
"msg": "eyJjYWxsX2NvbnRyYWN0Ijp7ImRlc3RpbmF0aW9uX2NoYWluIjoiZXRoZXJldW0iLCJkZXN0aW5hdGlvbl9hZGRyZXNzIjoic291cmNlLWl0cy1jb250cmFjdCIsInBheWxvYWQiOiIwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA0MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA2MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwYTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAzNzM3NTY5MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxNjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwYzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGRlMGI2YjNhNzY0MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxNDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDIwMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAyMDIwMjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMjAwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDEwMTAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMCJ9fQ==",
10+
"funds": []
11+
}
12+
}
13+
},
14+
"gas_limit": null,
15+
"reply_on": "never"
16+
}
17+
],
18+
"attributes": [],
19+
"events": [
20+
{
21+
"type": "message_received",
22+
"attributes": [
23+
{
24+
"key": "cc_id",
25+
"value": "sui_message-id"
26+
},
27+
{
28+
"key": "destination_chain",
29+
"value": "ethereum"
30+
},
31+
{
32+
"key": "message_type",
33+
"value": "InterchainTransfer"
34+
},
35+
{
36+
"key": "token_id",
37+
"value": "0101010101010101010101010101010101010101010101010101010101010101"
38+
},
39+
{
40+
"key": "source_address",
41+
"value": "0202020202020202020202020202020202020202020202020202020202020202"
42+
},
43+
{
44+
"key": "destination_address",
45+
"value": "0101010101010101010101010101010101010101010101010101010101010101"
46+
},
47+
{
48+
"key": "amount",
49+
"value": "1000000000000000000"
50+
}
51+
]
52+
}
53+
],
54+
"data": null
55+
}

0 commit comments

Comments
 (0)