Address review comments

Change-Id: I4036e71f3df1dc419419930cfdffba302166e28d
This commit is contained in:
Hendrik Hofstadt 2021-07-30 19:02:04 +02:00
parent 24672a7b2f
commit 8ab3b669d9
11 changed files with 106 additions and 45 deletions

View File

@ -14,9 +14,7 @@ use crate::{
types::ConsistencyLevel, types::ConsistencyLevel,
CHAIN_ID_SOLANA, CHAIN_ID_SOLANA,
}; };
use solana_program::{ use solana_program::sysvar::clock::Clock;
sysvar::clock::Clock,
};
use solitaire::{ use solitaire::{
processors::seeded::Seeded, processors::seeded::Seeded,
trace, trace,
@ -81,7 +79,8 @@ pub fn post_message(
trace!("Emitter Address: {}", accs.emitter.info().key); trace!("Emitter Address: {}", accs.emitter.info().key);
trace!("Nonce: {}", data.nonce); trace!("Nonce: {}", data.nonce);
accs.sequence.verify_derivation(ctx.program_id, &(&*accs).into())?; accs.sequence
.verify_derivation(ctx.program_id, &(&*accs).into())?;
let msg_derivation = MessageDerivationData { let msg_derivation = MessageDerivationData {
emitter_key: accs.emitter.key.to_bytes(), emitter_key: accs.emitter.key.to_bytes(),
@ -121,7 +120,7 @@ pub fn post_message(
.create(&(&*accs).into(), ctx, accs.payer.key, Exempt)?; .create(&(&*accs).into(), ctx, accs.payer.key, Exempt)?;
} }
trace!("Sequence: {}", accs.sequence.sequence); trace!("Sequence: {}", accs.sequence.sequence);
// Initialize transfer // Initialize transfer
trace!("Setting Message Details"); trace!("Setting Message Details");

View File

@ -29,6 +29,10 @@ use byteorder::{
BigEndian, BigEndian,
WriteBytesExt, WriteBytesExt,
}; };
use serde::{
Deserialize,
Serialize,
};
use sha3::Digest; use sha3::Digest;
use solana_program::program_error::ProgramError; use solana_program::program_error::ProgramError;
use solitaire::{ use solitaire::{
@ -39,10 +43,6 @@ use std::io::{
Cursor, Cursor,
Write, Write,
}; };
use serde::{
Deserialize,
Serialize
};
impl From<&PostVAAData> for GuardianSetDerivationData { impl From<&PostVAAData> for GuardianSetDerivationData {
fn from(data: &PostVAAData) -> Self { fn from(data: &PostVAAData) -> Self {

View File

@ -16,7 +16,14 @@ use byteorder::{
ReadBytesExt, ReadBytesExt,
}; };
use primitive_types::U256; use primitive_types::U256;
use solana_program::pubkey::Pubkey; use serde::{
Deserialize,
Serialize,
};
use solana_program::{
program_error::ProgramError::InvalidAccountData,
pubkey::Pubkey,
};
use solitaire::{ use solitaire::{
processors::seeded::{ processors::seeded::{
AccountOwner, AccountOwner,
@ -36,10 +43,6 @@ use std::{
}, },
str::FromStr, str::FromStr,
}; };
use serde::{
Deserialize,
Serialize,
};
#[derive(Default, BorshSerialize, BorshDeserialize, Serialize, Deserialize)] #[derive(Default, BorshSerialize, BorshDeserialize, Serialize, Deserialize)]
pub struct GuardianSetData { pub struct GuardianSetData {
@ -237,8 +240,8 @@ impl SerializePayload for GovernancePayloadUpgrade {
} }
impl DeserializePayload for GovernancePayloadUpgrade impl DeserializePayload for GovernancePayloadUpgrade
where where
Self: DeserializeGovernancePayload, Self: DeserializeGovernancePayload,
{ {
fn deserialize(buf: &mut &[u8]) -> Result<Self, SolitaireError> { fn deserialize(buf: &mut &[u8]) -> Result<Self, SolitaireError> {
let mut c = Cursor::new(buf); let mut c = Cursor::new(buf);
@ -247,6 +250,10 @@ impl DeserializePayload for GovernancePayloadUpgrade
let mut addr = [0u8; 32]; let mut addr = [0u8; 32];
c.read_exact(&mut addr)?; c.read_exact(&mut addr)?;
if c.position() != c.into_inner().len() as u64 {
return Err(InvalidAccountData.into());
}
Ok(GovernancePayloadUpgrade { Ok(GovernancePayloadUpgrade {
new_contract: Pubkey::new(&addr[..]), new_contract: Pubkey::new(&addr[..]),
}) })
@ -282,8 +289,8 @@ impl SerializePayload for GovernancePayloadGuardianSetChange {
} }
impl DeserializePayload for GovernancePayloadGuardianSetChange impl DeserializePayload for GovernancePayloadGuardianSetChange
where where
Self: DeserializeGovernancePayload, Self: DeserializeGovernancePayload,
{ {
fn deserialize(buf: &mut &[u8]) -> Result<Self, SolitaireError> { fn deserialize(buf: &mut &[u8]) -> Result<Self, SolitaireError> {
let mut c = Cursor::new(buf); let mut c = Cursor::new(buf);
@ -299,6 +306,10 @@ impl DeserializePayload for GovernancePayloadGuardianSetChange
keys.push(key); keys.push(key);
} }
if c.position() != c.into_inner().len() as u64 {
return Err(InvalidAccountData.into());
}
Ok(GovernancePayloadGuardianSetChange { Ok(GovernancePayloadGuardianSetChange {
new_guardian_set_index: new_index, new_guardian_set_index: new_index,
new_guardian_set: keys, new_guardian_set: keys,
@ -330,8 +341,8 @@ impl SerializePayload for GovernancePayloadSetMessageFee {
} }
impl DeserializePayload for GovernancePayloadSetMessageFee impl DeserializePayload for GovernancePayloadSetMessageFee
where where
Self: DeserializeGovernancePayload, Self: DeserializeGovernancePayload,
{ {
fn deserialize(buf: &mut &[u8]) -> Result<Self, SolitaireError> { fn deserialize(buf: &mut &[u8]) -> Result<Self, SolitaireError> {
let mut c = Cursor::new(buf); let mut c = Cursor::new(buf);
@ -341,6 +352,10 @@ impl DeserializePayload for GovernancePayloadSetMessageFee
c.read_exact(&mut fee_data)?; c.read_exact(&mut fee_data)?;
let fee = U256::from_big_endian(&fee_data); let fee = U256::from_big_endian(&fee_data);
if c.position() != c.into_inner().len() as u64 {
return Err(InvalidAccountData.into());
}
Ok(GovernancePayloadSetMessageFee { fee }) Ok(GovernancePayloadSetMessageFee { fee })
} }
} }
@ -372,8 +387,8 @@ impl SerializePayload for GovernancePayloadTransferFees {
} }
impl DeserializePayload for GovernancePayloadTransferFees impl DeserializePayload for GovernancePayloadTransferFees
where where
Self: DeserializeGovernancePayload, Self: DeserializeGovernancePayload,
{ {
fn deserialize(buf: &mut &[u8]) -> Result<Self, SolitaireError> { fn deserialize(buf: &mut &[u8]) -> Result<Self, SolitaireError> {
let mut c = Cursor::new(buf); let mut c = Cursor::new(buf);
@ -386,6 +401,10 @@ impl DeserializePayload for GovernancePayloadTransferFees
let mut to = ForeignAddress::default(); let mut to = ForeignAddress::default();
c.read_exact(&mut to)?; c.read_exact(&mut to)?;
if c.position() != c.into_inner().len() as u64 {
return Err(InvalidAccountData.into());
}
Ok(GovernancePayloadTransferFees { amount, to }) Ok(GovernancePayloadTransferFees { amount, to })
} }
} }

View File

@ -3,6 +3,7 @@ use crate::{
Claim, Claim,
ClaimDerivationData, ClaimDerivationData,
}, },
api::ForeignAddress,
error::Error::{ error::Error::{
InvalidGovernanceAction, InvalidGovernanceAction,
InvalidGovernanceChain, InvalidGovernanceChain,
@ -17,6 +18,10 @@ use byteorder::{
BigEndian, BigEndian,
ReadBytesExt, ReadBytesExt,
}; };
use serde::{
Deserialize,
Serialize,
};
use solana_program::pubkey::Pubkey; use solana_program::pubkey::Pubkey;
use solitaire::{ use solitaire::{
processors::seeded::Seeded, processors::seeded::Seeded,
@ -37,8 +42,6 @@ use std::{
}, },
ops::Deref, ops::Deref,
}; };
use crate::api::ForeignAddress;
use serde::{Deserialize, Serialize};
pub trait SerializePayload: Sized { pub trait SerializePayload: Sized {
fn serialize<W: Write>(&self, writer: &mut W) -> std::result::Result<(), SolitaireError>; fn serialize<W: Write>(&self, writer: &mut W) -> std::result::Result<(), SolitaireError>;
@ -110,8 +113,8 @@ pub struct PayloadMessage<'b, T: DeserializePayload>(
impl<'a, 'b: 'a, 'c, T: DeserializePayload> Peel<'a, 'b, 'c> for PayloadMessage<'b, T> { impl<'a, 'b: 'a, 'c, T: DeserializePayload> Peel<'a, 'b, 'c> for PayloadMessage<'b, T> {
fn peel<I>(ctx: &'c mut Context<'a, 'b, 'c, I>) -> Result<Self> fn peel<I>(ctx: &'c mut Context<'a, 'b, 'c, I>) -> Result<Self>
where where
Self: Sized, Self: Sized,
{ {
// Deserialize wrapped payload // Deserialize wrapped payload
let data: Data<'b, PostedMessage, { AccountState::Initialized }> = Data::peel(ctx)?; let data: Data<'b, PostedMessage, { AccountState::Initialized }> = Data::peel(ctx)?;

View File

@ -14,7 +14,10 @@ use crate::{
types::*, types::*,
TokenBridgeError::*, TokenBridgeError::*,
}; };
use bridge::vaa::ClaimableVAA; use bridge::{
vaa::ClaimableVAA,
CHAIN_ID_SOLANA,
};
use solana_program::{ use solana_program::{
account_info::AccountInfo, account_info::AccountInfo,
program::invoke_signed, program::invoke_signed,
@ -83,11 +86,13 @@ pub fn complete_native(
) -> Result<()> { ) -> Result<()> {
// Verify the chain registration // Verify the chain registration
let derivation_data: EndpointDerivationData = (&*accs).into(); let derivation_data: EndpointDerivationData = (&*accs).into();
accs.chain_registration.verify_derivation(ctx.program_id, &derivation_data)?; accs.chain_registration
.verify_derivation(ctx.program_id, &derivation_data)?;
// Verify that the custody account is derived correctly // Verify that the custody account is derived correctly
let derivation_data: CustodyAccountDerivationData = (&*accs).into(); let derivation_data: CustodyAccountDerivationData = (&*accs).into();
accs.custody.verify_derivation(ctx.program_id, &derivation_data)?; accs.custody
.verify_derivation(ctx.program_id, &derivation_data)?;
// Verify mints // Verify mints
if *accs.mint.info().key != accs.to.mint { if *accs.mint.info().key != accs.to.mint {
@ -107,6 +112,9 @@ pub fn complete_native(
if accs.vaa.token_chain != 1 { if accs.vaa.token_chain != 1 {
return Err(InvalidChain.into()); return Err(InvalidChain.into());
} }
if accs.vaa.to_chain != CHAIN_ID_SOLANA {
return Err(InvalidChain.into());
}
// Prevent vaa double signing // Prevent vaa double signing
accs.vaa.verify(ctx.program_id)?; accs.vaa.verify(ctx.program_id)?;
@ -187,13 +195,19 @@ pub fn complete_wrapped(
// Verify mint // Verify mint
let derivation_data: WrappedDerivationData = (&*accs).into(); let derivation_data: WrappedDerivationData = (&*accs).into();
accs.mint.verify_derivation(ctx.program_id, &derivation_data)?; accs.mint
.verify_derivation(ctx.program_id, &derivation_data)?;
// Verify mints // Verify mints
if *accs.mint.info().key != accs.to.mint { if *accs.mint.info().key != accs.to.mint {
return Err(InvalidMint.into()); return Err(InvalidMint.into());
} }
// Verify VAA
if accs.vaa.to_chain != CHAIN_ID_SOLANA {
return Err(InvalidChain.into());
}
accs.vaa.verify(ctx.program_id)?; accs.vaa.verify(ctx.program_id)?;
accs.vaa.claim(ctx, accs.payer.key)?; accs.vaa.claim(ctx, accs.payer.key)?;

View File

@ -4,8 +4,8 @@ use crate::{
Endpoint, Endpoint,
EndpointDerivationData, EndpointDerivationData,
MintSigner, MintSigner,
WrappedMetaDerivationData,
WrappedDerivationData, WrappedDerivationData,
WrappedMetaDerivationData,
WrappedMint, WrappedMint,
WrappedTokenMeta, WrappedTokenMeta,
}, },
@ -92,13 +92,16 @@ pub fn create_wrapped(
data: CreateWrappedData, data: CreateWrappedData,
) -> Result<()> { ) -> Result<()> {
let derivation_data: WrappedDerivationData = (&*accs).into(); let derivation_data: WrappedDerivationData = (&*accs).into();
accs.mint.verify_derivation(ctx.program_id, &derivation_data)?; accs.mint
.verify_derivation(ctx.program_id, &derivation_data)?;
let meta_derivation_data: WrappedMetaDerivationData = (&*accs).into(); let meta_derivation_data: WrappedMetaDerivationData = (&*accs).into();
accs.meta.verify_derivation(ctx.program_id, &meta_derivation_data)?; accs.meta
.verify_derivation(ctx.program_id, &meta_derivation_data)?;
let derivation_data: EndpointDerivationData = (&*accs).into(); let derivation_data: EndpointDerivationData = (&*accs).into();
accs.chain_registration.verify_derivation(ctx.program_id, &derivation_data)?; accs.chain_registration
.verify_derivation(ctx.program_id, &derivation_data)?;
accs.vaa.verify(ctx.program_id)?; accs.vaa.verify(ctx.program_id)?;
accs.vaa.claim(ctx, accs.payer.key)?; accs.vaa.claim(ctx, accs.payer.key)?;

View File

@ -9,7 +9,10 @@ use crate::{
PayloadGovernanceRegisterChain, PayloadGovernanceRegisterChain,
}, },
types::*, types::*,
TokenBridgeError::InvalidGovernanceKey, TokenBridgeError::{
InvalidChain,
InvalidGovernanceKey,
},
}; };
use bridge::{ use bridge::{
vaa::{ vaa::{
@ -151,13 +154,18 @@ pub fn register_chain(
data: RegisterChainData, data: RegisterChainData,
) -> Result<()> { ) -> Result<()> {
let derivation_data: EndpointDerivationData = (&*accs).into(); let derivation_data: EndpointDerivationData = (&*accs).into();
accs.endpoint.verify_derivation(ctx.program_id, &derivation_data)?; accs.endpoint
.verify_derivation(ctx.program_id, &derivation_data)?;
// Claim VAA // Claim VAA
verify_governance(&accs.vaa); verify_governance(&accs.vaa);
accs.vaa.verify(&ctx.program_id)?; accs.vaa.verify(&ctx.program_id)?;
accs.vaa.claim(ctx, accs.payer.key)?; accs.vaa.claim(ctx, accs.payer.key)?;
if accs.vaa.chain == CHAIN_ID_SOLANA {
return Err(InvalidChain.into());
}
// Create endpoint // Create endpoint
accs.endpoint accs.endpoint
.create(&((&*accs).into()), ctx, accs.payer.key, Exempt); .create(&((&*accs).into()), ctx, accs.payer.key, Exempt);

View File

@ -282,10 +282,8 @@ pub fn transfer_wrapped(
// Verify that meta is correct // Verify that meta is correct
let derivation_data: WrappedMetaDerivationData = (&*accs).into(); let derivation_data: WrappedMetaDerivationData = (&*accs).into();
accs.wrapped_meta.verify_derivation( accs.wrapped_meta
ctx.program_id, .verify_derivation(ctx.program_id, &derivation_data)?;
&derivation_data,
)?;
// Burn tokens // Burn tokens
let burn_ix = spl_token::instruction::burn( let burn_ix = spl_token::instruction::burn(

View File

@ -216,9 +216,7 @@ pub fn create_wrapped(
&program_id, &program_id,
); );
let mint_meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key( let mint_meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
&WrappedMetaDerivationData { &WrappedMetaDerivationData { mint_key },
mint_key,
},
&program_id, &program_id,
); );
let mint_authority_key = MintSigner::key(None, &program_id); let mint_authority_key = MintSigner::key(None, &program_id);

View File

@ -25,7 +25,10 @@ use byteorder::{
use primitive_types::U256; use primitive_types::U256;
use solana_program::{ use solana_program::{
native_token::Sol, native_token::Sol,
program_error::ProgramError, program_error::{
ProgramError,
ProgramError::InvalidAccountData,
},
pubkey::Pubkey, pubkey::Pubkey,
}; };
use solitaire::SolitaireError; use solitaire::SolitaireError;
@ -82,6 +85,10 @@ impl DeserializePayload for PayloadTransfer {
v.read_exact(&mut fee_data)?; v.read_exact(&mut fee_data)?;
let fee = U256::from_big_endian(&fee_data); let fee = U256::from_big_endian(&fee_data);
if v.position() != v.into_inner().len() as u64 {
return Err(InvalidAccountData.into());
}
Ok(PayloadTransfer { Ok(PayloadTransfer {
amount, amount,
token_address, token_address,
@ -155,6 +162,10 @@ impl DeserializePayload for PayloadAssetMeta {
.map_err::<SolitaireError, _>(|_| TokenBridgeError::InvalidUTF8String.into())?; .map_err::<SolitaireError, _>(|_| TokenBridgeError::InvalidUTF8String.into())?;
name = name.chars().filter(|c| c != &'\0').collect(); name = name.chars().filter(|c| c != &'\0').collect();
if v.position() != v.into_inner().len() as u64 {
return Err(InvalidAccountData.into());
}
Ok(PayloadAssetMeta { Ok(PayloadAssetMeta {
token_address, token_address,
token_chain, token_chain,
@ -219,6 +230,10 @@ where
let mut endpoint_address = [0u8; 32]; let mut endpoint_address = [0u8; 32];
v.read_exact(&mut endpoint_address)?; v.read_exact(&mut endpoint_address)?;
if v.position() != v.into_inner().len() as u64 {
return Err(InvalidAccountData.into());
}
Ok(PayloadGovernanceRegisterChain { Ok(PayloadGovernanceRegisterChain {
chain, chain,
endpoint_address, endpoint_address,
@ -265,6 +280,10 @@ where
let mut addr = [0u8; 32]; let mut addr = [0u8; 32];
c.read_exact(&mut addr)?; c.read_exact(&mut addr)?;
if c.position() != c.into_inner().len() as u64 {
return Err(InvalidAccountData.into());
}
Ok(GovernancePayloadUpgrade { Ok(GovernancePayloadUpgrade {
new_contract: Pubkey::new(&addr[..]), new_contract: Pubkey::new(&addr[..]),
}) })