Fix AnchorVaa struct (#308)

* Deployment address and fix deser bug

* Format
This commit is contained in:
guibescos 2022-09-27 19:40:40 -05:00 committed by GitHub
parent 4cec02d4da
commit 834e045812
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 51 additions and 21 deletions

View File

@ -4906,7 +4906,7 @@ dependencies = [
[[package]]
name = "wormhole-core"
version = "0.1.0"
source = "git+https://github.com/guibescos/wormhole?branch=gbescos/sdk-solana#2a6169c646a78d76407323d138fa4aeb09b1655a"
source = "git+https://github.com/guibescos/wormhole?branch=reisen/sdk-solana#61bb2fb691a8df0aa0e42a21632e43b392ffa90f"
dependencies = [
"borsh",
"bstr",
@ -4922,7 +4922,7 @@ dependencies = [
[[package]]
name = "wormhole-solana"
version = "0.1.0"
source = "git+https://github.com/guibescos/wormhole?branch=gbescos/sdk-solana#2a6169c646a78d76407323d138fa4aeb09b1655a"
source = "git+https://github.com/guibescos/wormhole?branch=reisen/sdk-solana#61bb2fb691a8df0aa0e42a21632e43b392ffa90f"
dependencies = [
"borsh",
"bstr",

View File

@ -20,8 +20,8 @@ overflow-checks = true
[dependencies]
anchor-lang = {version = "0.25.0", features = ["init-if-needed"]}
wormhole-solana = { git = "https://github.com/guibescos/wormhole", branch = "gbescos/sdk-solana"}
wormhole-core = { git = "https://github.com/guibescos/wormhole", branch = "gbescos/sdk-solana"}
wormhole-solana = { git = "https://github.com/guibescos/wormhole", branch = "reisen/sdk-solana"}
wormhole-core = { git = "https://github.com/guibescos/wormhole", branch = "reisen/sdk-solana"}
boolinator = "2.4.0"
[dev-dependencies]

View File

@ -8,4 +8,5 @@ pub enum ExecutorError {
GovernanceHeaderInvalidModule,
GovernanceHeaderInvalidAction,
GovernanceHeaderInvalidReceiverChain,
PostedVaaHeaderWrongMagicNumber,
}

View File

@ -17,13 +17,13 @@ use wormhole::Chain::{
};
mod error;
mod state;
pub mod state;
#[cfg(test)]
mod tests;
//Anchor requires the program to declare its own id
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
declare_id!("exe6S3AxPVNmy46L4Nj6HrnnAVQUhwyYzMSNcnRn3qq");
#[program]
pub mod remote_executor {
@ -65,14 +65,14 @@ pub mod remote_executor {
}
}
const EXECUTOR_KEY_SEED: &str = "EXECUTOR_KEY";
const CLAIM_RECORD_SEED: &str = "CLAIM_RECORD";
pub const EXECUTOR_KEY_SEED: &str = "EXECUTOR_KEY";
pub const CLAIM_RECORD_SEED: &str = "CLAIM_RECORD";
#[derive(Accounts)]
pub struct ExecutePostedVaa<'info> {
#[account(mut)]
pub payer: Signer<'info>,
#[account(constraint = Chain::from(posted_vaa.emitter_chain) == Solana @ ExecutorError::EmitterChainNotSolana, constraint = posted_vaa.sequence > claim_record.sequence @ExecutorError::NonIncreasingSequence )]
#[account(constraint = Chain::from(posted_vaa.emitter_chain) == Solana @ ExecutorError::EmitterChainNotSolana, constraint = posted_vaa.sequence > claim_record.sequence @ExecutorError::NonIncreasingSequence, constraint = (&posted_vaa.magic == b"vaa" || &posted_vaa.magic == b"msg" || &posted_vaa.magic == b"msu") @ExecutorError::PostedVaaHeaderWrongMagicNumber )]
pub posted_vaa: Account<'info, AnchorVaa>,
/// The reason claim_record has different seeds than executor_key is that executor key might need to pay in the CPI, so we want it to be a native wallet
#[account(init_if_needed, space = 8 + get_packed_len::<ClaimRecord>(), payer=payer, seeds = [CLAIM_RECORD_SEED.as_bytes(), &posted_vaa.emitter_address], bump)]

View File

@ -49,5 +49,6 @@ impl Deref for AnchorVaa {
#[derive(Clone, AnchorDeserialize, AnchorSerialize)]
pub struct AnchorVaa {
pub magic: [u8; 3],
pub vaa: VAA,
}

View File

@ -74,6 +74,7 @@ pub enum VaaAttack {
WrongOwner,
WrongData,
WrongEmitterChain,
WrongVaaMagic,
}
impl ExecutorBench {
@ -154,6 +155,11 @@ impl ExecutorBench {
_ => Chain::Solana.into(),
};
let vaa_magic = match validity {
VaaAttack::WrongVaaMagic => b"xxx",
_ => b"vaa",
};
let owner: Pubkey = match validity {
VaaAttack::WrongOwner => Pubkey::new_unique(),
_ => AnchorVaa::owner(),
@ -169,17 +175,20 @@ impl ExecutorBench {
let payload_bytes = payload.try_to_vec().unwrap();
let vaa = VAA {
vaa_version: 0,
consistency_level: 0,
vaa_time: 0,
vaa_signature_account: Pubkey::new_unique(),
submission_time: 0,
nonce: 0,
sequence: self.seqno.get(&emitter).unwrap_or(&0) + 1,
emitter_chain,
emitter_address: emitter.to_bytes(),
payload: payload_bytes,
let vaa = AnchorVaa {
magic: *vaa_magic,
vaa: VAA {
vaa_version: 0,
consistency_level: 0,
vaa_time: 0,
vaa_signature_account: Pubkey::new_unique(),
submission_time: 0,
nonce: 0,
sequence: self.seqno.get(&emitter).unwrap_or(&0) + 1,
emitter_chain,
emitter_address: emitter.to_bytes(),
payload: payload_bytes,
},
};
*self.seqno.entry(*emitter).or_insert(0) += 1;
@ -278,7 +287,7 @@ impl ExecutorSimulator {
signers: &Vec<&Keypair>,
executor_attack: ExecutorAttack,
) -> Result<(), BanksClientError> {
let posted_vaa_data: VAA = self
let posted_vaa_data: AnchorVaa = self
.banks_client
.get_account_data_with_borsh(*posted_vaa_address)
.await

View File

@ -73,6 +73,16 @@ async fn test_adversarial() {
VaaAttack::WrongEmitterChain,
);
let vaa_account_wrong_vaa_magic = bench.add_vaa_account(
&emitter,
&vec![transfer(
&executor_key,
&&receiver,
Rent::default().minimum_balance(0),
)],
VaaAttack::WrongVaaMagic,
);
// The goal of this account is creating a claim_record that the attacker is going to try to use to impersonate
// the right claim_record
let vaa_account_valid_2 = bench.add_vaa_account(&emitter_2, &vec![], VaaAttack::None);
@ -115,6 +125,15 @@ async fn test_adversarial() {
ExecutorError::EmitterChainNotSolana.into()
);
// VAA has wrong magic number
assert_eq!(
sim.execute_posted_vaa(&vaa_account_wrong_vaa_magic, &vec![], ExecutorAttack::None)
.await
.unwrap_err()
.unwrap(),
ExecutorError::PostedVaaHeaderWrongMagicNumber.into()
);
// Claim record does not correspond to the emitter's claim record
// Next error is privilege scalation because anchor tries to create the account at wrong address but signing with the right seeds
assert_eq!(