2022-12-15 02:24:26 -08:00
|
|
|
mod helpers;
|
|
|
|
|
|
|
|
use cosmwasm_std::{to_binary, Event};
|
2023-01-18 01:06:13 -08:00
|
|
|
use global_accountant::msg::ChainRegistrationResponse;
|
2022-12-15 02:24:26 -08:00
|
|
|
use helpers::*;
|
2023-04-18 09:31:38 -07:00
|
|
|
use wormhole_sdk::{
|
2022-12-15 02:24:26 -08:00
|
|
|
token::{Action, GovernancePacket},
|
|
|
|
vaa::Body,
|
|
|
|
Address, Chain,
|
|
|
|
};
|
|
|
|
|
|
|
|
fn create_vaa_body() -> Body<GovernancePacket> {
|
|
|
|
Body {
|
|
|
|
timestamp: 1,
|
|
|
|
nonce: 1,
|
|
|
|
emitter_chain: Chain::Solana,
|
2023-04-18 09:31:38 -07:00
|
|
|
emitter_address: wormhole_sdk::GOVERNANCE_EMITTER,
|
2022-12-15 02:24:26 -08:00
|
|
|
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() {
|
2022-12-19 00:31:04 -08:00
|
|
|
let (wh, mut contract) = proper_instantiate();
|
2022-12-15 02:24:26 -08:00
|
|
|
|
|
|
|
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() {
|
2022-12-19 00:31:04 -08:00
|
|
|
let (wh, mut contract) = proper_instantiate();
|
2022-12-15 02:24:26 -08:00
|
|
|
|
|
|
|
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() {
|
2022-12-19 00:31:04 -08:00
|
|
|
let (wh, mut contract) = proper_instantiate();
|
2022-12-15 02:24:26 -08:00
|
|
|
|
|
|
|
let mut body = create_vaa_body();
|
|
|
|
body.payload.chain = Chain::Oasis;
|
|
|
|
|
|
|
|
let (_, data) = sign_vaa_body(&wh, body);
|
2023-03-13 17:29:15 -07:00
|
|
|
let err = contract
|
2022-12-15 02:24:26 -08:00
|
|
|
.submit_vaas(vec![data])
|
|
|
|
.expect_err("successfully executed chain registration VAA for different chain");
|
2023-03-13 17:29:15 -07:00
|
|
|
assert_eq!(
|
2023-03-14 08:58:05 -07:00
|
|
|
"this token governance vaa is for another chain",
|
2023-03-13 17:29:15 -07:00
|
|
|
err.root_cause().to_string().to_lowercase()
|
|
|
|
);
|
2022-12-15 02:24:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn non_governance_chain() {
|
2022-12-19 00:31:04 -08:00
|
|
|
let (wh, mut contract) = proper_instantiate();
|
2022-12-15 02:24:26 -08:00
|
|
|
|
|
|
|
let mut body = create_vaa_body();
|
|
|
|
body.emitter_chain = Chain::Fantom;
|
|
|
|
|
|
|
|
let (_, data) = sign_vaa_body(&wh, body);
|
2023-03-13 17:29:15 -07:00
|
|
|
let err = contract
|
2022-12-15 02:24:26 -08:00
|
|
|
.submit_vaas(vec![data])
|
|
|
|
.expect_err("successfully executed chain registration with non-governance chain");
|
2023-03-13 17:29:15 -07:00
|
|
|
|
2023-03-14 08:58:05 -07:00
|
|
|
// A governance message with wrong chain or emitter will be parsed as a token bridge message
|
|
|
|
assert!(err
|
|
|
|
.source()
|
|
|
|
.unwrap()
|
|
|
|
.to_string()
|
|
|
|
.contains("failed to parse tokenbridge message",));
|
2022-12-15 02:24:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn non_governance_emitter() {
|
2022-12-19 00:31:04 -08:00
|
|
|
let (wh, mut contract) = proper_instantiate();
|
2022-12-15 02:24:26 -08:00
|
|
|
|
|
|
|
let mut body = create_vaa_body();
|
|
|
|
body.emitter_address = Address([0x88; 32]);
|
|
|
|
|
|
|
|
let (_, data) = sign_vaa_body(&wh, body);
|
2023-03-13 17:29:15 -07:00
|
|
|
let err = contract
|
2022-12-15 02:24:26 -08:00
|
|
|
.submit_vaas(vec![data])
|
|
|
|
.expect_err("successfully executed chain registration with non-governance emitter");
|
2023-03-13 17:29:15 -07:00
|
|
|
|
2023-03-14 08:58:05 -07:00
|
|
|
// A governance message with wrong chain or emitter will be parsed as a token bridge message
|
|
|
|
assert!(err
|
|
|
|
.source()
|
|
|
|
.unwrap()
|
|
|
|
.to_string()
|
|
|
|
.contains("failed to parse tokenbridge message",));
|
2022-12-15 02:24:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn duplicate() {
|
2022-12-19 00:31:04 -08:00
|
|
|
let (wh, mut contract) = proper_instantiate();
|
2022-12-15 02:24:26 -08:00
|
|
|
|
|
|
|
let (_, data) = sign_vaa_body(&wh, create_vaa_body());
|
|
|
|
contract
|
|
|
|
.submit_vaas(vec![data.clone()])
|
|
|
|
.expect("failed to submit chain registration");
|
|
|
|
|
2023-03-13 17:29:15 -07:00
|
|
|
let err = contract
|
2022-12-15 02:24:26 -08:00
|
|
|
.submit_vaas(vec![data])
|
|
|
|
.expect_err("successfully submitted duplicate vaa");
|
2023-03-13 17:29:15 -07:00
|
|
|
assert_eq!(
|
|
|
|
"message already processed",
|
|
|
|
err.root_cause().to_string().to_lowercase()
|
|
|
|
);
|
2022-12-15 02:24:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn no_quorum() {
|
2022-12-19 00:31:04 -08:00
|
|
|
let (wh, mut contract) = proper_instantiate();
|
2022-12-15 02:24:26 -08:00
|
|
|
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();
|
|
|
|
|
2023-03-13 17:29:15 -07:00
|
|
|
let err = contract
|
2022-12-15 02:24:26 -08:00
|
|
|
.submit_vaas(vec![data])
|
|
|
|
.expect_err("successfully executed chain registration without a quorum of signatures");
|
2023-03-13 17:29:15 -07:00
|
|
|
assert_eq!(
|
|
|
|
"generic error: querier contract error: no quorum",
|
|
|
|
err.root_cause().to_string().to_lowercase()
|
|
|
|
);
|
2022-12-15 02:24:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn bad_signature() {
|
2022-12-19 00:31:04 -08:00
|
|
|
let (wh, mut contract) = proper_instantiate();
|
2022-12-15 02:24:26 -08:00
|
|
|
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();
|
2023-03-13 17:29:15 -07:00
|
|
|
let err = contract
|
2022-12-15 02:24:26 -08:00
|
|
|
.submit_vaas(vec![data])
|
|
|
|
.expect_err("successfully executed chain registration with bad signature");
|
2023-03-13 17:29:15 -07:00
|
|
|
assert_eq!(
|
2023-04-14 13:04:49 -07:00
|
|
|
"generic error: querier contract error: failed to recover verifying key",
|
2023-03-13 17:29:15 -07:00
|
|
|
err.root_cause().to_string().to_lowercase()
|
|
|
|
);
|
2022-12-15 02:24:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn bad_serialization() {
|
2022-12-19 00:31:04 -08:00
|
|
|
let (wh, mut contract) = proper_instantiate();
|
2022-12-15 02:24:26 -08:00
|
|
|
|
|
|
|
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();
|
|
|
|
|
2023-03-13 17:29:15 -07:00
|
|
|
let err = contract
|
2022-12-15 02:24:26 -08:00
|
|
|
.submit_vaas(vec![data])
|
|
|
|
.expect_err("successfully executed chain registration with bad serialization");
|
2023-03-13 17:29:15 -07:00
|
|
|
assert_eq!(
|
|
|
|
"unexpected end of input",
|
|
|
|
err.root_cause().to_string().to_lowercase()
|
|
|
|
);
|
2022-12-15 02:24:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn non_chain_registration() {
|
2022-12-19 00:31:04 -08:00
|
|
|
let (wh, mut contract) = proper_instantiate();
|
2022-12-15 02:24:26 -08:00
|
|
|
|
|
|
|
let mut body = create_vaa_body();
|
|
|
|
body.payload.action = Action::ContractUpgrade {
|
|
|
|
new_contract: Address([0x2f; 32]),
|
|
|
|
};
|
|
|
|
let (_, data) = sign_vaa_body(&wh, body);
|
|
|
|
|
2023-03-13 17:29:15 -07:00
|
|
|
let err = contract
|
2022-12-15 02:24:26 -08:00
|
|
|
.submit_vaas(vec![data])
|
|
|
|
.expect_err("successfully executed VAA with non-chain registration action");
|
2023-03-13 17:29:15 -07:00
|
|
|
assert_eq!(
|
|
|
|
"unsupported governance action",
|
|
|
|
err.root_cause().to_string().to_lowercase()
|
|
|
|
);
|
2022-12-15 02:24:26 -08:00
|
|
|
}
|