From 3a20ec9b0d6596548ca54cd92da64d0b487e93c2 Mon Sep 17 00:00:00 2001 From: Hendrik Hofstadt Date: Mon, 28 Jun 2021 14:26:55 +0200 Subject: [PATCH] Clean up terra program Change-Id: I2a323e80dc4d72c0405f50eaaf23e04b1e875246 --- terra/contracts/wormhole/src/contract.rs | 718 +----------------- terra/contracts/wormhole/src/lib.rs | 4 - terra/contracts/wormhole/src/state.rs | 2 +- terra/contracts/wormhole/tests/integration.rs | 90 --- 4 files changed, 5 insertions(+), 809 deletions(-) delete mode 100644 terra/contracts/wormhole/tests/integration.rs diff --git a/terra/contracts/wormhole/src/contract.rs b/terra/contracts/wormhole/src/contract.rs index b926ff38..53c7a3ba 100644 --- a/terra/contracts/wormhole/src/contract.rs +++ b/terra/contracts/wormhole/src/contract.rs @@ -1,7 +1,6 @@ use cosmwasm_std::{ has_coins, log, to_binary, Api, BankMsg, Binary, Coin, CosmosMsg, Env, Extern, HandleResponse, HumanAddr, InitResponse, Querier, StdError, StdResult, Storage, - WasmMsg }; use crate::byte_utils::extend_address_to_32; @@ -9,7 +8,7 @@ use crate::byte_utils::ByteUtils; use crate::error::ContractError; use crate::msg::{GetAddressHexResponse, GetStateResponse, GuardianSetInfoResponse, HandleMsg, InitMsg, QueryMsg}; use crate::state::{ - config, config_read, guardian_set_get, guardian_set_set, vaa_archive_add, vaa_archive_check, + config, config_read, guardian_set_get, guardian_set_set, vaa_archive_check, ConfigInfo, GovernancePacket, GuardianAddress, GuardianSetInfo, GuardianSetUpgrade, ParsedVAA, TransferFee, }; @@ -33,7 +32,7 @@ const FEE_DENOMINATION: &str = "uluna"; pub fn init( deps: &mut Extern, - env: Env, + _env: Env, msg: InitMsg, ) -> StdResult { // Save general wormhole info @@ -96,7 +95,7 @@ fn handle_governance_payload( let module: String = module.chars().filter(|c| !c.is_whitespace()).collect(); if module != "core" { - return Err(StdError::generic_err("this is not a valid module")) + return Err(StdError::generic_err("this is not a valid module")); } match gov_packet.action { @@ -155,7 +154,7 @@ fn parse_and_verify_vaa( &data[pos + ParsedVAA::SIG_DATA_POS ..pos + ParsedVAA::SIG_DATA_POS + ParsedVAA::SIG_DATA_LEN], ) - .or_else(|_| ContractError::CannotDecodeSignature.std_err())?; + .or_else(|_| ContractError::CannotDecodeSignature.std_err())?; let id = RecoverableId::new(data.get_u8(pos + ParsedVAA::SIG_RECOVERY_POS)) .or_else(|_| ContractError::CannotDecodeSignature.std_err())?; let recoverable_signature = RecoverableSignature::new(&signature, id) @@ -354,712 +353,3 @@ fn keys_equal(a: &VerifyKey, b: &GuardianAddress) -> bool { } true } - -#[cfg(test)] -mod tests { - use super::*; - use crate::state::GuardianSetInfo; - use cosmwasm_std::testing::{mock_dependencies, mock_env, MOCK_CONTRACT_ADDR}; - use cosmwasm_std::{HumanAddr, QuerierResult}; - use serde_json; - - // Constants generated by bridge/cmd/vaa-test-terra/main.go - const ADDR_1: &str = "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe"; - const ADDR_2: &str = "E06A9ADfeB38a8eE4D00E89307C016D0749679bD"; - const ADDR_3: &str = "8575Df9b3c97B4E267Deb92d93137844A97A0132"; - const ADDR_4: &str = "0427cDA59902Dc6EB0c1bd2b6D38F87c5552b348"; - const ADDR_5: &str = "bFEa822F75c42e1764c791B8fE04a7B10DDB3857"; - const ADDR_6: &str = "2F5FE0B158147e7260f14062556AfC94Eece55fF"; - const VAA_VALID_TRANSFER_1_SIG: &str = "01000000000100d106d4f363c6e3d0bf8ebf3cf8ef1ba35e66687b7613a826b5f5b68e0c346e1e0fdd6ceb332c87dad7d170ee6736571c0b75173787a8dcf41a492075e18a9a9601000007d01000000038010302010400000000000000000000000000000000000000000000000000000000000000000000000000000000000102030405060708090001020304050607080900010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000"; - const VAA_VALID_TRANSFER_2_SIGS: &str = "0100000000020040d91705d211c52c9f120adb1b794355ba10ec1ff855295e677c5b341b2e5449684179f8ca4087e88de2cba0e6cbf6e0c7a353529800ccf96e5fdd80a85a59220001efb8a4825c87ab68190e1b184eeda5c45f82b22450ff113f2581a2f1bd3aeca60798392405cd4d3b523a5c3426d09b963c195c842a0040e93651cb700785d0e600000007d0100000003801030201040000000000000000000000000000000000000000000000000000000000000000000000000000000000010203040506070809000102030405060708090002000000000000000000000000d833215cbcc3f914bd1c9ece3ee7bf8b14f841bb080000000000000000000000000000000000000000000000000de0b6b3a7640000"; - const VAA_VALID_TRANSFER_3_SIGS: &str = "0100000000030040d91705d211c52c9f120adb1b794355ba10ec1ff855295e677c5b341b2e5449684179f8ca4087e88de2cba0e6cbf6e0c7a353529800ccf96e5fdd80a85a59220001efb8a4825c87ab68190e1b184eeda5c45f82b22450ff113f2581a2f1bd3aeca60798392405cd4d3b523a5c3426d09b963c195c842a0040e93651cb700785d0e60002a5fb92ff2b5a5eed98e2909ed932e5d9328cb2527027cce8f40c4f5677c341c83fe9fac7bf39af60fe47ecfb6f52b22b9d817d24d4147684b08e2fe19ff3a3ef01000007d0100000003801030201040000000000000000000000000000000000000000000000000000000000000000000000000000000000010203040506070809000102030405060708090002000000000000000000000000d833215cbcc3f914bd1c9ece3ee7bf8b14f841bb080000000000000000000000000000000000000000000000000de0b6b3a7640000"; - const VAA_VALID_GUARDIAN_SET_CHANGE_FROM_0: &str = "01000000000100a33c022217ccb87a5bc83b71e6377fff6639e7904d9e9995a42dc0867dc2b0bc5d1aacc3752ea71cf4d85278526b5dd40b0343667a2d4434a44cbf7844181a1000000007d0010000000101e06a9adfeb38a8ee4d00e89307c016d0749679bd"; - const VAA_ERROR_SIGNATURE_SEQUENCE: &str = "01000000000201efb8a4825c87ab68190e1b184eeda5c45f82b22450ff113f2581a2f1bd3aeca60798392405cd4d3b523a5c3426d09b963c195c842a0040e93651cb700785d0e6000040d91705d211c52c9f120adb1b794355ba10ec1ff855295e677c5b341b2e5449684179f8ca4087e88de2cba0e6cbf6e0c7a353529800ccf96e5fdd80a85a592200000007d0100000003801030201040000000000000000000000000000000000000000000000000000000000000000000000000000000000010203040506070809000102030405060708090002000000000000000000000000d833215cbcc3f914bd1c9ece3ee7bf8b14f841bb080000000000000000000000000000000000000000000000000de0b6b3a7640000"; - const VAA_ERROR_WRONG_SIGNATURE_1_SIG: &str = "0100000000010075c1b20fb59adc55a08f9778bc525507a36a29d1f0e2cb3fcc9c90f7331786263c4bd53ce5d3865b4f63cddeafb2c1026b5e13f1b66af7dabbd1f1af9f34fd3f01000007d01000000038010302010400000000000000000000000000000000000000000000000000000000000000000000000000000000000102030405060708090001020304050607080900010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000"; - const VAA_VALID_GUARDIAN_SET_CHANGE_FROM_0_DIFF: &str = "01000000000100d90d6f9cbc0458599cbe4d267bc9221b54955b94cb5cb338aeb845bdc9dd275f558871ea479de9cc0b44cfb2a07344431a3adbd2f98aa86f4e12ff4aba061b7f00000007d00100000001018575df9b3c97b4e267deb92d93137844a97a0132"; - const VAA_ERROR_INVALID_TARGET_ADDRESS: &str = "0100000000010092f32c76aa3a8d83de59b3f2281cfbf70af33d9bcfbaa78bd3e9cafc512335ab40b126a894f0182ee8c69f5324496eb681c1780ed39bcc80f589cfc0a5df144a01000007d01000000038010302010400000000000000000000000000000000000000000000000000000000000000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000"; - const VAA_VALID_GUARDIAN_SET_CHANGE_JUMP: &str = "010000000001004b179853b36b76446c72944d50551be814ab34f23da2124615315da71505df801b38355d741cdd65e856792e2a1435270abfe52ae005c4e3671c0b7aac36445a01000007d00100000002018575df9b3c97b4e267deb92d93137844a97a0132"; - const VAA_ERROR_AMOUNT_TOO_HIGH: &str = "0100000000010055fdf76a64b779ac5b7a54dc181cf430f4d14a499b7933049d8bc94db529ed0a2d12d50ec2026883e59a5c64f2189b60c84a53b66113e8b52da66fd89f70495f00000007d01000000038010302010400000000000000000000000000000000000000000000000000000000000000000000000000000000000102030405060708090001020304050607080900010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000100000000000000000000000000000000"; - const VAA_ERROR_SAME_SOURCE_AND_TARGET: &str = "010000000001004c53dfce8fc9e781f0cfdc6592c00c337c1e109168ff17ee3bf4cf69ddb8a0a52a3c215093301d5459d282d625dc5125592609f06f14a57f61121e668b0ec10500000003e81000000038030302010400000000000000000000000000000000000000000000000000000000000000000000000000000000000102030405060708090001020304050607080900010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000"; - const VAA_ERROR_WRONG_TARGET: &str = "01000000000100b19a265b1407e9619ffc29be9562161ed2c155db5ba68e01265a250a677eb0c62bb91e468da827e9ec4c1e9428ade97129126f56500c4a3c9f9803cc85f656d200000003e81000000038010202010400000000000000000000000000000000000000000000000000000000000000000000000000000000000102030405060708090001020304050607080900010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000"; - const VAA_VALID_GUARDIAN_SET_CHANGE_TO_6: &str = "01000000000100a5defbd912ef327d07afff71e0da9c2e2a13e5516255c62e249a6761afe2465c7b6fc1032451559551e76eb4a029474fd791b2250c4fd40a8b3f5d4f5f58e5a30000000fa0010000000106befa429d57cd18b7f8a4d91a2da9ab4af05d0fbee06a9adfeb38a8ee4d00e89307c016d0749679bd8575df9b3c97b4e267deb92d93137844a97a01320427cda59902dc6eb0c1bd2b6d38f87c5552b348bfea822f75c42e1764c791b8fe04a7b10ddb38572f5fe0b158147e7260f14062556afc94eece55ff"; - const VAA_VALID_TRANSFER_5_SIGS_GS_1: &str = "01000000010500027eb7e87a9d0ab91ec53bb073c0f0acf189900139daa652666fd4cfe32a4ee42383c1a66e3a397c2de8ae485225357feb52f665952b1e384ef6dfcea1ba9f920001cfcacfad444ac3202f8f0d2252c69ee90d18c9105f7be3b5d361b7fcb0fbf7fa7287bac5de9cb02f86a28fdd7f24015991020431b0048aa3bbb29daed625e416000372f6c239ddeccded04a95a0cf0bfefe6e168148f1fe3b93e797eb2e74e098b890f2be341dd0f3c8172c2050154407cfdd1ea7bd6cce0b31f020ec7530ffb6109000449c025fe0630268983d57c4bd1546497788f810e427b6fd436cb1f048152375e1063422b4d1cc668a0612814c550ea7e3d1aa93404a0b6e089d210d4c937023a000548bf474fb350d5e482378c37404fb4d1421e262d13ebf6b11977214c789a246a6c278a522a9be4beba008f3d481b1ee35c5b0559bef474eb34b9e3e681947c230100000fa01000000039010302010500000000000000000000000000000000000000000000000000000000000000000000000000000000000102030405060708090001020304050607080900010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000"; - - const CANONICAL_LENGTH: usize = 20; - - const CREATOR_ADDR: &str = "creator"; - const SENDER_ADDR: &str = "sender"; - const SENDER_ADDR_HEX: &str = "73656e6465720000000000000000000000000000"; // Extended to 20 bytes - - lazy_static! { - static ref ALL_GUARDIANS: Vec = vec![ - GuardianAddress::from(ADDR_1), - GuardianAddress::from(ADDR_2), - GuardianAddress::from(ADDR_3), - GuardianAddress::from(ADDR_4), - GuardianAddress::from(ADDR_5), - GuardianAddress::from(ADDR_6) - ]; - } - - fn unix_timestamp() -> u64 { - 1608803487u64 // Use deterministic timestamp - } - - fn do_init_with_guardians( - deps: &mut Extern, - number_of_guardians: usize, - ) { - let expiration_time = unix_timestamp() + 1000; - do_init(deps, &ALL_GUARDIANS[..number_of_guardians], expiration_time); - } - - fn do_init( - deps: &mut Extern, - guardians: &[GuardianAddress], - expiration_time: u64, - ) { - let init_msg = InitMsg { - initial_guardian_set: GuardianSetInfo { - addresses: guardians.to_vec(), - expiration_time, - }, - guardian_set_expirity: 50, - wrapped_asset_code_id: 999, - }; - let mut env = mock_env(&HumanAddr::from(CREATOR_ADDR), &[]); - env.block.time = unix_timestamp(); - let res = init(deps, env, init_msg).unwrap(); - assert_eq!(0, res.messages.len()); - } - - fn submit_msg( - deps: &mut Extern, - msg: HandleMsg, - ) -> StdResult { - submit_msg_with_sender(deps, msg, &HumanAddr::from(SENDER_ADDR), None) - } - - fn submit_msg_with_fee( - deps: &mut Extern, - msg: HandleMsg, - fee: Coin, - ) -> StdResult { - submit_msg_with_sender(deps, msg, &HumanAddr::from(SENDER_ADDR), Some(fee)) - } - - fn submit_msg_with_sender( - deps: &mut Extern, - msg: HandleMsg, - sender: &HumanAddr, - fee: Option, - ) -> StdResult { - let mut env = mock_env(sender, &[]); - env.block.time = unix_timestamp(); - if let Some(fee) = fee { - env.message.sent_funds = vec![fee]; - } - - handle(deps, env, msg) - } - - fn submit_vaa( - deps: &mut Extern, - vaa: &str, - ) -> StdResult { - submit_msg( - deps, - HandleMsg::SubmitVAA { - vaa: hex::decode(vaa).expect("Decoding failed").into(), - }, - ) - } - - #[test] - fn can_init() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - } - - #[test] - fn valid_vaa_token_transfer() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let messages = submit_vaa(&mut deps, VAA_VALID_TRANSFER_1_SIG) - .unwrap() - .messages; - assert_eq!(1, messages.len()); - let msg = &messages[0]; - match msg { - CosmosMsg::Wasm(wasm_msg) => match wasm_msg { - WasmMsg::Instantiate { - code_id, - msg: _, - send, - label, - } => { - assert_eq!(*code_id, 999); - assert_eq!(*label, None); - assert_eq!(*send, vec![]); - } - _ => panic!("Wrong message type"), - }, - _ => panic!("Wrong message type"), - } - } - - #[test] - fn valid_vaa_2_signatures() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 2); - - let result = submit_vaa(&mut deps, VAA_VALID_TRANSFER_2_SIGS); - assert!(result.is_ok()); - } - - #[test] - fn valid_vaa_non_expiring_guardians() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init(&mut deps, &vec![GuardianAddress::from(ADDR_1)], 0); - - let result = submit_vaa(&mut deps, VAA_VALID_TRANSFER_1_SIG); - assert!(result.is_ok()); - } - - #[test] - fn error_vaa_same_vaa_twice() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let _ = submit_vaa(&mut deps, VAA_VALID_TRANSFER_1_SIG).unwrap(); - let e = submit_vaa(&mut deps, VAA_VALID_TRANSFER_1_SIG).unwrap_err(); - assert_eq!(e, ContractError::VaaAlreadyExecuted.std()); - } - - #[test] - fn valid_vaa_guardian_set_change() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let messages = submit_vaa(&mut deps, VAA_VALID_GUARDIAN_SET_CHANGE_FROM_0) - .unwrap() - .messages; - assert_eq!(0, messages.len()); - - // Check storage - let state = config_read(&deps.storage) - .load() - .expect("Cannot load config storage"); - assert_eq!(state.guardian_set_index, 1); - let guardian_set_info = guardian_set_get(&deps.storage, state.guardian_set_index) - .expect("Cannot find guardian set"); - assert_eq!( - guardian_set_info, - GuardianSetInfo { - addresses: vec![GuardianAddress::from(ADDR_2)], - expiration_time: 0 - } - ); - } - - #[test] - fn error_vaa_guardian_set_expired() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - // Expiration time 1 second in the past - let expiration_time = unix_timestamp() - 1; - do_init( - &mut deps, - &vec![GuardianAddress::from(ADDR_1)], - expiration_time, - ); - - let result = submit_vaa(&mut deps, VAA_VALID_TRANSFER_1_SIG); - assert_eq!(result, ContractError::GuardianSetExpired.std_err()); - } - - #[test] - fn error_vaa_no_quorum() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 2); - - let result = submit_vaa(&mut deps, VAA_VALID_TRANSFER_1_SIG); - assert_eq!(result, ContractError::NoQuorum.std_err()); - } - - #[test] - fn valid_partial_quorum() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 4); - - // 3 signatures on 4-guardian set is quorum - let result = submit_vaa(&mut deps, VAA_VALID_TRANSFER_3_SIGS); - assert!(result.is_ok()); - } - - #[test] - fn error_vaa_wrong_guardian_index_order() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 2); - - let result = submit_vaa(&mut deps, VAA_ERROR_SIGNATURE_SEQUENCE); - assert_eq!(result, ContractError::WrongGuardianIndexOrder.std_err()); - } - - #[test] - fn error_vaa_too_many_signatures() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let result = submit_vaa(&mut deps, VAA_VALID_TRANSFER_2_SIGS); - assert_eq!(result, ContractError::TooManySignatures.std_err()); - } - - #[test] - fn error_vaa_invalid_signature() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init( - &mut deps, - // Use 1-2-4 guardians - &vec![ - GuardianAddress::from(ADDR_1), - GuardianAddress::from(ADDR_2), - GuardianAddress::from(ADDR_4), - ], - unix_timestamp(), - ); - // Sign by 1-2-3 guardians - let result = submit_vaa(&mut deps, VAA_VALID_TRANSFER_3_SIGS); - assert_eq!(result, ContractError::GuardianSignatureError.std_err()); - - // Single signature, wrong key - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let result = submit_vaa(&mut deps, VAA_ERROR_WRONG_SIGNATURE_1_SIG); - assert_eq!(result, ContractError::GuardianSignatureError.std_err()); - } - - #[test] - fn error_vaa_not_current_quardian_set() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let result = submit_vaa(&mut deps, VAA_VALID_GUARDIAN_SET_CHANGE_FROM_0); - assert!(result.is_ok()); - - // Submit another valid change, which will fail, because now set #1 is active - // (we need to send a different VAA, because otherwise it will be blocked by duplicate check) - let result = submit_vaa(&mut deps, VAA_VALID_GUARDIAN_SET_CHANGE_FROM_0_DIFF); - assert_eq!(result, ContractError::NotCurrentGuardianSet.std_err()); - } - - #[test] - fn error_vaa_wrong_target_address_format() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let result = submit_vaa(&mut deps, VAA_ERROR_INVALID_TARGET_ADDRESS); - assert_eq!(result, ContractError::WrongTargetAddressFormat.std_err()); - } - - #[test] - fn error_vaa_guardian_set_change_index_not_increasing() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let result = submit_vaa(&mut deps, VAA_VALID_GUARDIAN_SET_CHANGE_JUMP); - assert_eq!( - result, - ContractError::GuardianSetIndexIncreaseError.std_err() - ); - } - - #[test] - fn error_vaa_transfer_amount_too_high() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let result = submit_vaa(&mut deps, VAA_ERROR_AMOUNT_TOO_HIGH); - assert_eq!(result, ContractError::AmountTooHigh.std_err()); - } - - #[test] - fn error_vaa_transfer_same_source_and_target() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let result = submit_vaa(&mut deps, VAA_ERROR_SAME_SOURCE_AND_TARGET); - assert_eq!(result, ContractError::SameSourceAndTarget.std_err()); - } - - #[test] - fn error_vaa_transfer_wrong_target_chain() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let result = submit_vaa(&mut deps, VAA_ERROR_WRONG_TARGET); - assert_eq!(result, ContractError::WrongTargetChain.std_err()); - } - - #[test] - fn valid_transfer_after_guardian_set_change() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let result = submit_vaa(&mut deps, VAA_VALID_TRANSFER_5_SIGS_GS_1); - assert_eq!(result, ContractError::InvalidGuardianSetIndex.std_err()); - - let result = submit_vaa(&mut deps, VAA_VALID_GUARDIAN_SET_CHANGE_TO_6); - assert!(result.is_ok()); - - let result = submit_vaa(&mut deps, VAA_VALID_TRANSFER_5_SIGS_GS_1); - assert!(result.is_ok()); - } - - const LOCK_ASSET_ADDR: &str = "lockassetaddr"; - const LOCK_ASSET_ADDR_HEX: &str = "6c6f636b61737365746164647200000000000000"; // Extended to 20 bytes - const LOCK_NONCE: u32 = 105; - const LOCK_AMOUNT: u128 = 10000000000; - const LOCK_RECIPIENT: &str = "0000000000000000000011223344556677889900"; - const LOCK_TARGET: u8 = 1; - const LOCK_WRAPPED_CHAIN: u16 = 2; - const LOCK_WRAPPED_ASSET: &str = "112233445566ff"; - const LOCKED_DECIMALS: u8 = 11; - const ADDRESS_EXTENSION: &str = "000000000000000000000000"; - const LOCK_ASSET_ID: &[u8] = b"testassetid"; - struct LockAssetQuerier {} - - lazy_static! { - static ref MSG_LOCK: HandleMsg = HandleMsg::LockAssets { - asset: HumanAddr::from(LOCK_ASSET_ADDR), - amount: Uint128::from(LOCK_AMOUNT), - recipient: Binary::from(hex::decode(LOCK_RECIPIENT).unwrap()), - target_chain: LOCK_TARGET, - nonce: LOCK_NONCE, - }; - } - - impl Querier for LockAssetQuerier { - fn raw_query(&self, bin_request: &[u8]) -> QuerierResult { - let query_request: QueryRequest<()> = serde_json::from_slice(bin_request).unwrap(); - let query = if let QueryRequest::Wasm(wasm_query) = query_request { - wasm_query - } else { - panic!("Wrong request type"); - }; - let msg: Binary = if let WasmQuery::Smart { contract_addr, msg } = query { - assert_eq!(contract_addr, HumanAddr::from(LOCK_ASSET_ADDR)); - msg - } else { - panic!("Wrong query type"); - }; - let msg: WrappedQuery = serde_json::from_slice(msg.as_slice()).unwrap(); - let response = match msg { - WrappedQuery::TokenInfo {} => serde_json::to_string(&TokenInfoResponse { - name: String::from("Test"), - symbol: String::from("TST"), - decimals: LOCKED_DECIMALS, - total_supply: Uint128::from(1000000000000u128), - }) - .unwrap(), - WrappedQuery::WrappedAssetInfo {} => { - serde_json::to_string(&WrappedAssetInfoResponse { - asset_chain: LOCK_WRAPPED_CHAIN, - asset_address: Binary::from(hex::decode(LOCK_WRAPPED_ASSET).unwrap()), - bridge: HumanAddr::from("bridgeaddr"), - }) - .unwrap() - } - _ => panic!("Wrong msg type"), - }; - Ok(Ok(Binary::from(response.as_bytes()))) - } - } - - #[test] - fn error_lock_fee_too_low() { - let deps = mock_dependencies(CANONICAL_LENGTH, &[]); - let mut deps = Extern { - storage: deps.storage, - api: deps.api, - querier: LockAssetQuerier {}, - }; - do_init_with_guardians(&mut deps, 1); - - // No fee - let result = submit_msg(&mut deps, MSG_LOCK.clone()); - assert_eq!(result, ContractError::FeeTooLow.std_err()); - - // Amount too low - let result = submit_msg_with_fee(&mut deps, MSG_LOCK.clone(), Coin::new(9999, "uluna")); - assert_eq!(result, ContractError::FeeTooLow.std_err()); - - // Wrong denomination - let result = submit_msg_with_fee(&mut deps, MSG_LOCK.clone(), Coin::new(10000, "uusd")); - assert_eq!(result, ContractError::FeeTooLow.std_err()); - } - - #[test] - fn valid_lock_regular_asset() { - let deps = mock_dependencies(CANONICAL_LENGTH, &[]); - let mut deps = Extern { - storage: deps.storage, - api: deps.api, - querier: LockAssetQuerier {}, - }; - do_init_with_guardians(&mut deps, 1); - - let result = - submit_msg_with_fee(&mut deps, MSG_LOCK.clone(), Coin::new(10000, "uluna")).unwrap(); - - let expected_logs = vec![ - log("locked.target_chain", LOCK_TARGET), - log("locked.token_chain", CHAIN_ID), // Regular asset is Terra-based - log("locked.token_decimals", LOCKED_DECIMALS), - log( - "locked.token", - format!("{}{}", ADDRESS_EXTENSION, LOCK_ASSET_ADDR_HEX), - ), - log( - "locked.sender", - format!("{}{}", ADDRESS_EXTENSION, SENDER_ADDR_HEX), - ), - log("locked.recipient", LOCK_RECIPIENT), - log("locked.amount", LOCK_AMOUNT), - log("locked.nonce", LOCK_NONCE), - log("locked.block_time", unix_timestamp()), - ]; - assert_eq!(result.log, expected_logs); - assert_eq!(result.messages.len(), 1); - let msg = &result.messages[0]; - let wasm_msg = if let CosmosMsg::Wasm(wasm_msg) = msg { - wasm_msg - } else { - panic!("Wrong msg type"); - }; - let command_msg = if let WasmMsg::Execute { - contract_addr, msg, .. - } = wasm_msg - { - assert_eq!(*contract_addr, HumanAddr::from(LOCK_ASSET_ADDR)); - msg - } else { - panic!("Wrong wasm msg type"); - }; - let command_msg: TokenMsg = serde_json::from_slice(command_msg.as_slice()).unwrap(); - if let TokenMsg::TransferFrom { - owner, - recipient, - amount, - } = command_msg - { - assert_eq!(owner, HumanAddr::from(SENDER_ADDR)); - assert_eq!(recipient, HumanAddr::from(MOCK_CONTRACT_ADDR)); - assert_eq!(amount, Uint128::from(LOCK_AMOUNT)); - } else { - panic!("Wrong command type"); - } - } - - #[test] - fn error_lock_deployed_asset() { - let deps = mock_dependencies(CANONICAL_LENGTH, &[]); - let mut deps = Extern { - storage: deps.storage, - api: deps.api, - querier: LockAssetQuerier {}, - }; - do_init_with_guardians(&mut deps, 1); - - let register_msg = HandleMsg::RegisterAssetHook { - asset_id: Binary::from(LOCK_ASSET_ID), - }; - - let result = submit_msg_with_sender( - &mut deps, - register_msg.clone(), - &HumanAddr::from(LOCK_ASSET_ADDR), - None, - ); - - assert_eq!(result, ContractError::RegistrationForbidden.std_err()); - } - - #[test] - fn valid_lock_deployed_asset() { - let deps = mock_dependencies(CANONICAL_LENGTH, &[]); - let mut deps = Extern { - storage: deps.storage, - api: deps.api, - querier: LockAssetQuerier {}, - }; - do_init_with_guardians(&mut deps, 1); - - let register_msg = HandleMsg::RegisterAssetHook { - asset_id: Binary::from(LOCK_ASSET_ID), - }; - - wrapped_asset(&mut deps.storage) - .save(&LOCK_ASSET_ID, &HumanAddr::from(WRAPPED_ASSET_UPDATING)) - .unwrap(); - - let result = submit_msg_with_sender( - &mut deps, - register_msg.clone(), - &HumanAddr::from(LOCK_ASSET_ADDR), - None, - ); - - assert!(result.is_ok()); - - let result = - submit_msg_with_fee(&mut deps, MSG_LOCK.clone(), Coin::new(10000, "uluna")).unwrap(); - - let expected_logs = vec![ - log("locked.target_chain", LOCK_TARGET), - log("locked.token_chain", LOCK_WRAPPED_CHAIN), - log("locked.token_decimals", LOCKED_DECIMALS), - log("locked.token", LOCK_WRAPPED_ASSET), - log( - "locked.sender", - format!("{}{}", ADDRESS_EXTENSION, SENDER_ADDR_HEX), - ), - log("locked.recipient", LOCK_RECIPIENT), - log("locked.amount", LOCK_AMOUNT), - log("locked.nonce", LOCK_NONCE), - log("locked.block_time", unix_timestamp()), - ]; - assert_eq!(result.log, expected_logs); - assert_eq!(result.messages.len(), 1); - - let msg = &result.messages[0]; - let wasm_msg = if let CosmosMsg::Wasm(wasm_msg) = msg { - wasm_msg - } else { - panic!("Wrong msg type"); - }; - let command_msg = if let WasmMsg::Execute { - contract_addr, msg, .. - } = wasm_msg - { - assert_eq!(*contract_addr, HumanAddr::from(LOCK_ASSET_ADDR)); - msg - } else { - panic!("Wrong wasm msg type"); - }; - let command_msg: WrappedMsg = serde_json::from_slice(command_msg.as_slice()).unwrap(); - if let WrappedMsg::Burn { account, amount } = command_msg { - assert_eq!(account, HumanAddr::from(SENDER_ADDR)); - assert_eq!(amount, Uint128::from(LOCK_AMOUNT)); - } else { - panic!("Wrong command type"); - } - } - - #[test] - fn error_lock_same_source_and_target() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let mut msg = MSG_LOCK.clone(); - if let HandleMsg::LockAssets { - ref mut target_chain, - .. - } = msg - { - *target_chain = CHAIN_ID; - } - let result = submit_msg(&mut deps, msg); - assert_eq!(result, ContractError::SameSourceAndTarget.std_err()); - } - - #[test] - fn error_lock_amount_too_low() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 1); - - let mut msg = MSG_LOCK.clone(); - if let HandleMsg::LockAssets { ref mut amount, .. } = msg { - *amount = Uint128::zero(); - } - let result = submit_msg(&mut deps, msg); - assert_eq!(result, ContractError::AmountTooLow.std_err()); - } - - #[test] - fn valid_query_guardian_set() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 3); - - let result = query(&deps, QueryMsg::GuardianSetInfo {}).unwrap(); - let result: GuardianSetInfoResponse = serde_json::from_slice(result.as_slice()).unwrap(); - - assert_eq!( - result, - GuardianSetInfoResponse { - guardian_set_index: 0, - addresses: vec![ - GuardianAddress { - bytes: Binary::from(hex::decode(ADDR_1).unwrap()) - }, - GuardianAddress { - bytes: Binary::from(hex::decode(ADDR_2).unwrap()) - }, - GuardianAddress { - bytes: Binary::from(hex::decode(ADDR_3).unwrap()) - }, - ], - } - ) - } - - #[test] - fn valid_query_verify_vaa() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init_with_guardians(&mut deps, 4); - let env = mock_env(&HumanAddr::from(SENDER_ADDR), &[]); - - let decoded_vaa: Binary = hex::decode(VAA_VALID_TRANSFER_3_SIGS) - .expect("Decoding failed") - .into(); - let result = query( - &deps, - QueryMsg::VerifyVAA { - vaa: decoded_vaa, - block_time: env.block.time, - }, - ); - - assert!(result.is_ok()); - } - - #[test] - fn error_query_verify_vaa() { - let mut deps = mock_dependencies(CANONICAL_LENGTH, &[]); - do_init( - &mut deps, - // Use 1-2-4 guardians - &vec![ - GuardianAddress::from(ADDR_1), - GuardianAddress::from(ADDR_2), - GuardianAddress::from(ADDR_4), - ], - unix_timestamp(), - ); - let env = mock_env(&HumanAddr::from(SENDER_ADDR), &[]); - // Sign by 1-2-3 guardians - let decoded_vaa: Binary = hex::decode(VAA_VALID_TRANSFER_3_SIGS) - .expect("Decoding failed") - .into(); - let result = query( - &deps, - QueryMsg::VerifyVAA { - vaa: decoded_vaa, - block_time: env.block.time, - }, - ); - - assert_eq!(result, ContractError::GuardianSignatureError.std_err()); - } -} diff --git a/terra/contracts/wormhole/src/lib.rs b/terra/contracts/wormhole/src/lib.rs index f6737509..9117b3f1 100644 --- a/terra/contracts/wormhole/src/lib.rs +++ b/terra/contracts/wormhole/src/lib.rs @@ -1,7 +1,3 @@ -#[cfg(test)] -#[macro_use] -extern crate lazy_static; - pub mod byte_utils; pub mod contract; pub mod error; diff --git a/terra/contracts/wormhole/src/state.rs b/terra/contracts/wormhole/src/state.rs index 3bf5eeeb..3c5c23a9 100644 --- a/terra/contracts/wormhole/src/state.rs +++ b/terra/contracts/wormhole/src/state.rs @@ -354,6 +354,6 @@ mod tests { #[test] fn test_deserialize() { let x = vec![1u8,0u8,0u8,0u8,1u8,0u8,0u8,0u8,0u8,0u8,96u8,180u8,80u8,111u8,0u8,0u8,0u8,1u8,0u8,3u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,120u8,73u8,153u8,19u8,90u8,170u8,138u8,60u8,165u8,145u8,68u8,104u8,133u8,47u8,221u8,219u8,221u8,216u8,120u8,157u8,0u8,91u8,48u8,44u8,48u8,44u8,51u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,53u8,54u8,44u8,50u8,51u8,51u8,44u8,49u8,44u8,49u8,49u8,49u8,44u8,49u8,54u8,55u8,44u8,49u8,57u8,48u8,44u8,50u8,48u8,51u8,44u8,49u8,54u8,44u8,49u8,55u8,54u8,44u8,50u8,49u8,56u8,44u8,50u8,53u8,49u8,44u8,49u8,51u8,49u8,44u8,51u8,57u8,44u8,49u8,54u8,44u8,49u8,57u8,53u8,44u8,50u8,50u8,55u8,44u8,49u8,52u8,57u8,44u8,50u8,51u8,54u8,44u8,49u8,57u8,48u8,44u8,50u8,49u8,50u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,51u8,44u8,50u8,51u8,50u8,44u8,48u8,44u8,51u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,48u8,44u8,53u8,51u8,44u8,49u8,49u8,54u8,44u8,52u8,56u8,44u8,49u8,49u8,54u8,44u8,49u8,52u8,57u8,44u8,49u8,48u8,56u8,44u8,49u8,49u8,51u8,44u8,56u8,44u8,48u8,44u8,50u8,51u8,50u8,44u8,52u8,57u8,44u8,49u8,53u8,50u8,44u8,49u8,44u8,50u8,56u8,44u8,50u8,48u8,51u8,44u8,50u8,49u8,50u8,44u8,50u8,50u8,49u8,44u8,50u8,52u8,49u8,44u8,56u8,53u8,44u8,49u8,48u8,57u8,93u8]; - ParsedVAA::deserialize(x.as_slice()); + ParsedVAA::deserialize(x.as_slice()).unwrap(); } } diff --git a/terra/contracts/wormhole/tests/integration.rs b/terra/contracts/wormhole/tests/integration.rs deleted file mode 100644 index cdcd6f0d..00000000 --- a/terra/contracts/wormhole/tests/integration.rs +++ /dev/null @@ -1,90 +0,0 @@ -static WASM: &[u8] = include_bytes!("../../../target/wasm32-unknown-unknown/release/wormhole.wasm"); - -use cosmwasm_std::{from_slice, Env, HumanAddr, InitResponse, Coin}; -use cosmwasm_storage::to_length_prefixed; -use cosmwasm_vm::testing::{init, mock_env, mock_instance, MockApi, MockQuerier, MockStorage}; -use cosmwasm_vm::{Api, Instance, Storage}; - -use wormhole::msg::InitMsg; -use wormhole::state::{ConfigInfo, GuardianAddress, GuardianSetInfo, CONFIG_KEY}; - -use hex; - -enum TestAddress { - INITIALIZER, -} - -impl TestAddress { - fn value(&self) -> HumanAddr { - match self { - TestAddress::INITIALIZER => HumanAddr::from("initializer"), - } - } -} - -fn mock_env_height(signer: &HumanAddr, height: u64, time: u64) -> Env { - let mut env = mock_env(signer, &[]); - env.block.height = height; - env.block.time = time; - env -} - -fn get_config_info(storage: &S) -> ConfigInfo { - let key = to_length_prefixed(CONFIG_KEY); - let data = storage - .get(&key) - .0 - .expect("error getting data") - .expect("data should exist"); - from_slice(&data).expect("invalid data") -} - -fn do_init( - height: u64, - guardians: &Vec, -) -> Instance { - let mut deps = mock_instance(WASM, &[]); - let init_msg = InitMsg { - initial_guardian_set: GuardianSetInfo { - addresses: guardians.clone(), - expiration_time: 100, - }, - guardian_set_expirity: 50, - wrapped_asset_code_id: 999, - }; - let env = mock_env_height(&TestAddress::INITIALIZER.value(), height, 0); - let owner = deps - .api - .canonical_address(&TestAddress::INITIALIZER.value()) - .0 - .unwrap(); - let res: InitResponse = init(&mut deps, env, init_msg).unwrap(); - assert_eq!(0, res.messages.len()); - - // query the store directly - deps.with_storage(|storage| { - assert_eq!( - get_config_info(storage), - ConfigInfo { - guardian_set_index: 0, - guardian_set_expirity: 50, - wrapped_asset_code_id: 999, - owner, - fee: Coin::new(10000, "uluna"), - } - ); - Ok(()) - }) - .unwrap(); - deps -} - -#[test] -fn init_works() { - let guardians = vec![GuardianAddress::from(GuardianAddress { - bytes: hex::decode("beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe") - .expect("Decoding failed") - .into(), - })]; - let _deps = do_init(111, &guardians); -}