mod helpers; use cosmwasm_std::{to_binary, Event}; use helpers::*; use wormchain_accounting::msg::ChainRegistrationResponse; use wormhole::{ token::{Action, GovernancePacket}, vaa::Body, Address, Chain, }; fn create_vaa_body() -> Body { Body { timestamp: 1, nonce: 1, emitter_chain: Chain::Solana, emitter_address: wormhole::GOVERNANCE_EMITTER, sequence: 15920283, consistency_level: 0, payload: GovernancePacket { chain: Chain::Any, action: Action::RegisterChain { chain: Chain::Solana, emitter_address: Address([ 0xc6, 0x9a, 0x1b, 0x1a, 0x65, 0xdd, 0x33, 0x6b, 0xf1, 0xdf, 0x6a, 0x77, 0xaf, 0xb5, 0x01, 0xfc, 0x25, 0xdb, 0x7f, 0xc0, 0x93, 0x8c, 0xb0, 0x85, 0x95, 0xa9, 0xef, 0x47, 0x32, 0x65, 0xcb, 0x4f, ]), }, }, } } #[test] fn any_target() { let (wh, mut contract) = proper_instantiate(Vec::new(), Vec::new(), Vec::new()); let body = create_vaa_body(); let (v, data) = sign_vaa_body(&wh, body); let resp = contract .submit_vaas(vec![data]) .expect("failed to submit chain registration"); let Action::RegisterChain { chain, emitter_address } = v.payload.action else { panic!() }; resp.assert_event( &Event::new("wasm-RegisterChain") .add_attribute("chain", chain.to_string()) .add_attribute("emitter_address", emitter_address.to_string()), ); let ChainRegistrationResponse { address } = contract.query_chain_registration(chain.into()).unwrap(); assert_eq!(&*address, &emitter_address.0); } #[test] fn wormchain_target() { let (wh, mut contract) = proper_instantiate(Vec::new(), Vec::new(), Vec::new()); let mut body = create_vaa_body(); body.payload.chain = Chain::Wormchain; let (v, data) = sign_vaa_body(&wh, body); let resp = contract .submit_vaas(vec![data]) .expect("failed to submit chain registration"); let Action::RegisterChain { chain, emitter_address } = v.payload.action else { panic!() }; resp.assert_event( &Event::new("wasm-RegisterChain") .add_attribute("chain", chain.to_string()) .add_attribute("emitter_address", emitter_address.to_string()), ); let ChainRegistrationResponse { address } = contract.query_chain_registration(chain.into()).unwrap(); assert_eq!(&*address, &emitter_address.0); } #[test] fn wrong_target() { let (wh, mut contract) = proper_instantiate(Vec::new(), Vec::new(), Vec::new()); let mut body = create_vaa_body(); body.payload.chain = Chain::Oasis; let (_, data) = sign_vaa_body(&wh, body); contract .submit_vaas(vec![data]) .expect_err("successfully executed chain registration VAA for different chain"); } #[test] fn non_governance_chain() { let (wh, mut contract) = proper_instantiate(Vec::new(), Vec::new(), Vec::new()); let mut body = create_vaa_body(); body.emitter_chain = Chain::Fantom; let (_, data) = sign_vaa_body(&wh, body); contract .submit_vaas(vec![data]) .expect_err("successfully executed chain registration with non-governance chain"); } #[test] fn non_governance_emitter() { let (wh, mut contract) = proper_instantiate(Vec::new(), Vec::new(), Vec::new()); let mut body = create_vaa_body(); body.emitter_address = Address([0x88; 32]); let (_, data) = sign_vaa_body(&wh, body); contract .submit_vaas(vec![data]) .expect_err("successfully executed chain registration with non-governance emitter"); } #[test] fn duplicate() { let (wh, mut contract) = proper_instantiate(Vec::new(), Vec::new(), Vec::new()); let (_, data) = sign_vaa_body(&wh, create_vaa_body()); contract .submit_vaas(vec![data.clone()]) .expect("failed to submit chain registration"); contract .submit_vaas(vec![data]) .expect_err("successfully submitted duplicate vaa"); } #[test] fn no_quorum() { let (wh, mut contract) = proper_instantiate(Vec::new(), Vec::new(), Vec::new()); let index = wh.guardian_set_index(); let quorum = wh .calculate_quorum(index, contract.app().block_info().height) .unwrap() as usize; let (mut v, _) = sign_vaa_body(&wh, create_vaa_body()); v.signatures.truncate(quorum - 1); let data = serde_wormhole::to_vec(&v).map(From::from).unwrap(); contract .submit_vaas(vec![data]) .expect_err("successfully executed chain registration without a quorum of signatures"); } #[test] fn bad_signature() { let (wh, mut contract) = proper_instantiate(Vec::new(), Vec::new(), Vec::new()); let (mut v, _) = sign_vaa_body(&wh, create_vaa_body()); // Flip a bit in the first signature so it becomes invalid. v.signatures[0].signature[0] ^= 1; let data = serde_wormhole::to_vec(&v).map(From::from).unwrap(); contract .submit_vaas(vec![data]) .expect_err("successfully executed chain registration with bad signature"); } #[test] fn bad_serialization() { let (wh, mut contract) = proper_instantiate(Vec::new(), Vec::new(), Vec::new()); let (v, _) = sign_vaa_body(&wh, create_vaa_body()); // Rather than using the wormhole wire format use cosmwasm json. let data = to_binary(&v).unwrap(); contract .submit_vaas(vec![data]) .expect_err("successfully executed chain registration with bad serialization"); } #[test] fn non_chain_registration() { let (wh, mut contract) = proper_instantiate(Vec::new(), Vec::new(), Vec::new()); let mut body = create_vaa_body(); body.payload.action = Action::ContractUpgrade { new_contract: Address([0x2f; 32]), }; let (_, data) = sign_vaa_body(&wh, body); contract .submit_vaas(vec![data]) .expect_err("successfully executed VAA with non-chain registration action"); }