Verify emitter in all governance actions

Change-Id: Ib1fdbe9dc553e22a0e61d6f119eb45325d15861c
This commit is contained in:
Reisen 2021-07-07 08:48:37 +00:00 committed by Hendrik Hofstadt
parent fa75e3266a
commit 7ab5a93b21
2 changed files with 38 additions and 16 deletions

View File

@ -1,11 +1,9 @@
use solitaire::*; use solitaire::*;
use crate::types::{ use solana_program::{
GovernancePayloadSetMessageFee, program::invoke_signed,
GovernancePayloadTransferFees, pubkey::Pubkey,
}; };
use solana_program::pubkey::Pubkey;
use solitaire::{ use solitaire::{
processors::seeded::Seeded, processors::seeded::Seeded,
CreationLamports::Exempt, CreationLamports::Exempt,
@ -19,16 +17,40 @@ use crate::{
}, },
types::{ types::{
GovernancePayloadGuardianSetChange, GovernancePayloadGuardianSetChange,
GovernancePayloadSetMessageFee,
GovernancePayloadTransferFees,
GovernancePayloadUpgrade, GovernancePayloadUpgrade,
}, },
vaa::ClaimableVAA, vaa::{
ClaimableVAA,
DeserializePayload,
},
Error::{ Error::{
InvalidFeeRecipient, InvalidFeeRecipient,
InvalidGovernanceKey, InvalidGovernanceKey,
InvalidGuardianSetUpgrade, InvalidGuardianSetUpgrade,
}, },
CHAIN_ID_SOLANA,
}; };
use solana_program::program::invoke_signed;
// Confirm that a ClaimableVAA came from the correct chain, signed by the right emitter.
fn verify_claim<'a, T>(vaa: &ClaimableVAA<'a, T>) -> Result<()>
where
T: DeserializePayload,
{
let expected_emitter = std::env!("EMITTER_ADDRESS");
let current_emitter = format!(
"{}",
Pubkey::new_from_array(vaa.message.meta().emitter_address)
);
// Fail if the emitter is not the known governance key, or the emitting chain is not Solana.
if expected_emitter != current_emitter || vaa.message.meta().emitter_chain != CHAIN_ID_SOLANA {
Err(InvalidGovernanceKey.into())
} else {
Ok(())
}
}
#[derive(FromAccounts)] #[derive(FromAccounts)]
pub struct UpgradeContract<'b> { pub struct UpgradeContract<'b> {
@ -56,6 +78,8 @@ pub fn upgrade_contract(
accs: &mut UpgradeContract, accs: &mut UpgradeContract,
_data: UpgradeContractData, _data: UpgradeContractData,
) -> Result<()> { ) -> Result<()> {
verify_claim(&accs.vaa)?;
accs.vaa.claim(ctx, accs.payer.key)?; accs.vaa.claim(ctx, accs.payer.key)?;
let upgrade_ix = solana_program::bpf_loader_upgradeable::upgrade( let upgrade_ix = solana_program::bpf_loader_upgradeable::upgrade(
@ -111,15 +135,7 @@ pub fn upgrade_guardian_set(
accs: &mut UpgradeGuardianSet, accs: &mut UpgradeGuardianSet,
_data: UpgradeGuardianSetData, _data: UpgradeGuardianSetData,
) -> Result<()> { ) -> Result<()> {
// Enforce only the expected governance key. verify_claim(&accs.vaa)?;
if format!(
"{}",
Pubkey::new_from_array(accs.vaa.message.meta().emitter_address)
) != std::env!("EMITTER_ADDRESS")
|| accs.vaa.message.meta().emitter_chain != 1
{
return Err(InvalidGovernanceKey.into());
}
accs.vaa.claim(ctx, accs.payer.key)?; accs.vaa.claim(ctx, accs.payer.key)?;
@ -168,6 +184,8 @@ impl<'b> InstructionContext<'b> for SetFees<'b> {
pub struct SetFeesData {} pub struct SetFeesData {}
pub fn set_fees(ctx: &ExecutionContext, accs: &mut SetFees, _data: SetFeesData) -> Result<()> { pub fn set_fees(ctx: &ExecutionContext, accs: &mut SetFees, _data: SetFeesData) -> Result<()> {
verify_claim(&accs.vaa)?;
accs.vaa.claim(ctx, accs.payer.key)?; accs.vaa.claim(ctx, accs.payer.key)?;
accs.bridge.config.fee = accs.vaa.fee.as_u64(); accs.bridge.config.fee = accs.vaa.fee.as_u64();
@ -212,6 +230,8 @@ pub fn transfer_fees(
accs: &mut TransferFees, accs: &mut TransferFees,
_data: TransferFeesData, _data: TransferFeesData,
) -> Result<()> { ) -> Result<()> {
verify_claim(&accs.vaa)?;
accs.vaa.claim(ctx, accs.payer.key)?; accs.vaa.claim(ctx, accs.payer.key)?;
// Transfer fees // Transfer fees

View File

@ -74,6 +74,7 @@ pub struct BridgeConfig {
/// Amount of lamports that needs to be paid to the protocol to post a message /// Amount of lamports that needs to be paid to the protocol to post a message
pub fee: u64, pub fee: u64,
/// Amount of lamports that needs to be paid to the protocol to post a persistent message /// Amount of lamports that needs to be paid to the protocol to post a persistent message
pub fee_persistent: u64, pub fee_persistent: u64,
} }
@ -351,6 +352,7 @@ impl DeserializeGovernancePayload for GovernancePayloadSetMessageFee {
pub struct GovernancePayloadTransferFees { pub struct GovernancePayloadTransferFees {
// Amount to be transferred // Amount to be transferred
pub amount: U256, pub amount: U256,
// Recipient // Recipient
pub to: ForeignAddress, pub to: ForeignAddress,
} }