solana: couple modifications
* make burn_source optional * make verify_vaa_and_mint safer * uptick version 0.0.1-alpha.7
This commit is contained in:
parent
aa4ea707a3
commit
6c6a41c03d
|
@ -2377,7 +2377,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wormhole-cctp-solana"
|
name = "wormhole-cctp-solana"
|
||||||
version = "0.0.1-alpha.3"
|
version = "0.0.1-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anchor-lang",
|
"anchor-lang",
|
||||||
"anchor-spl",
|
"anchor-spl",
|
||||||
|
@ -2393,7 +2393,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wormhole-circle-integration-solana"
|
name = "wormhole-circle-integration-solana"
|
||||||
version = "0.0.1-alpha.3"
|
version = "0.0.1-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anchor-lang",
|
"anchor-lang",
|
||||||
"anchor-spl",
|
"anchor-spl",
|
||||||
|
|
|
@ -7,7 +7,7 @@ resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
version = "0.0.1-alpha.3"
|
version = "0.0.1-alpha.7"
|
||||||
authors = ["Wormhole Contributors"]
|
authors = ["Wormhole Contributors"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
homepage = "https://wormhole.com"
|
homepage = "https://wormhole.com"
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub struct BurnAndPublishArgs {
|
||||||
/// Token account where assets originated from. This pubkey is encoded in the [Deposit] message.
|
/// Token account where assets originated from. This pubkey is encoded in the [Deposit] message.
|
||||||
/// If this will be useful to an integrator, he should encode where the assets have been burned
|
/// If this will be useful to an integrator, he should encode where the assets have been burned
|
||||||
/// from if it was not burned directly when calling [burn_and_publish].
|
/// from if it was not burned directly when calling [burn_and_publish].
|
||||||
pub burn_source: Pubkey,
|
pub burn_source: Option<Pubkey>,
|
||||||
|
|
||||||
/// Destination caller address, which is encoded in the CCTP message. Only this address can
|
/// Destination caller address, which is encoded in the CCTP message. Only this address can
|
||||||
/// receive a CCTP message via the CCTP Message Transmitter.
|
/// receive a CCTP message via the CCTP Message Transmitter.
|
||||||
|
@ -73,6 +73,9 @@ pub fn burn_and_publish<'info>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let token_address = cctp_ctx.accounts.mint.key.to_bytes();
|
let token_address = cctp_ctx.accounts.mint.key.to_bytes();
|
||||||
|
let burn_source = burn_source
|
||||||
|
.unwrap_or(cctp_ctx.accounts.src_token.key())
|
||||||
|
.to_bytes();
|
||||||
|
|
||||||
// We want to make this call as early as possible because the deposit for burn
|
// We want to make this call as early as possible because the deposit for burn
|
||||||
// message is an Anchor event (i.e. written to the program log). We hope that integrators will
|
// message is an Anchor event (i.e. written to the program log). We hope that integrators will
|
||||||
|
@ -99,7 +102,7 @@ pub fn burn_and_publish<'info>(
|
||||||
source_cctp_domain,
|
source_cctp_domain,
|
||||||
destination_cctp_domain,
|
destination_cctp_domain,
|
||||||
cctp_nonce,
|
cctp_nonce,
|
||||||
burn_source: burn_source.to_bytes(),
|
burn_source,
|
||||||
mint_recipient,
|
mint_recipient,
|
||||||
payload,
|
payload,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -5,17 +5,16 @@ use wormhole_raw_vaas::cctp::WormholeCctpMessage;
|
||||||
|
|
||||||
/// Method to reconcile a CCTP message with a Wormhole VAA encoding the Wormhole CCTP deposit. After
|
/// Method to reconcile a CCTP message with a Wormhole VAA encoding the Wormhole CCTP deposit. After
|
||||||
/// reconciliation, the method invokes the CCTP Message Transmitter to mint the local tokens to the
|
/// reconciliation, the method invokes the CCTP Message Transmitter to mint the local tokens to the
|
||||||
/// provided token account in the account context. This method returns a zero-copy [VaaAccount]
|
/// provided token account in the account context.
|
||||||
/// reader so an integrator can verify emitter information.
|
|
||||||
///
|
///
|
||||||
/// This method reconciles both messages by making sure the source domain, destination domain and
|
/// This method reconciles both messages by making sure the source domain, destination domain and
|
||||||
/// nonce match.
|
/// nonce match.
|
||||||
///
|
///
|
||||||
/// NOTE: In order to return a zero-copy [VaaAccount] reader, this method takes a reference to the
|
/// NOTE: It is the integrator's responsibility to ensure that the owner of this account is Wormhole
|
||||||
/// [AccountInfo] of the VAA account. It is the integrator's responsibility to ensure that the owner
|
/// Core Bridge program if this method is used. Otherwise, please use [verify_vaa_and_mint], which
|
||||||
/// of this account is Wormhole Core Bridge program.
|
/// performs the account owner check.
|
||||||
pub fn verify_vaa_and_mint<'ctx, 'info>(
|
pub fn verify_vaa_and_mint_unchecked<'info>(
|
||||||
vaa: &'ctx AccountInfo<'info>,
|
vaa: &VaaAccount<'_>,
|
||||||
cctp_ctx: CpiContext<
|
cctp_ctx: CpiContext<
|
||||||
'_,
|
'_,
|
||||||
'_,
|
'_,
|
||||||
|
@ -24,9 +23,7 @@ pub fn verify_vaa_and_mint<'ctx, 'info>(
|
||||||
message_transmitter_program::cpi::ReceiveTokenMessengerMinterMessage<'info>,
|
message_transmitter_program::cpi::ReceiveTokenMessengerMinterMessage<'info>,
|
||||||
>,
|
>,
|
||||||
args: message_transmitter_program::cpi::ReceiveMessageArgs,
|
args: message_transmitter_program::cpi::ReceiveMessageArgs,
|
||||||
) -> Result<VaaAccount<'ctx>> {
|
) -> Result<()> {
|
||||||
let vaa = VaaAccount::load(vaa)?;
|
|
||||||
|
|
||||||
let msg = WormholeCctpMessage::try_from(vaa.try_payload()?)
|
let msg = WormholeCctpMessage::try_from(vaa.try_payload()?)
|
||||||
.map_err(|_| error!(WormholeCctpError::CannotParseMessage))?;
|
.map_err(|_| error!(WormholeCctpError::CannotParseMessage))?;
|
||||||
|
|
||||||
|
@ -70,6 +67,43 @@ pub fn verify_vaa_and_mint<'ctx, 'info>(
|
||||||
// Token Messenger Minter program to mint tokens.
|
// Token Messenger Minter program to mint tokens.
|
||||||
message_transmitter_program::cpi::receive_token_messenger_minter_message(cctp_ctx, args)?;
|
message_transmitter_program::cpi::receive_token_messenger_minter_message(cctp_ctx, args)?;
|
||||||
|
|
||||||
|
// Done.
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Method to reconcile a CCTP message with a Wormhole VAA encoding the Wormhole CCTP deposit. After
|
||||||
|
/// reconciliation, the method invokes the CCTP Message Transmitter to mint the local tokens to the
|
||||||
|
/// provided token account in the account context. This method returns a zero-copy [VaaAccount]
|
||||||
|
/// reader so an integrator can verify emitter information.
|
||||||
|
///
|
||||||
|
/// This method reconciles both messages by making sure the source domain, destination domain and
|
||||||
|
/// nonce match.
|
||||||
|
///
|
||||||
|
/// NOTE: In order to return a zero-copy [VaaAccount] reader, this method takes a reference to the
|
||||||
|
/// [AccountInfo] of the VAA account.
|
||||||
|
pub fn verify_vaa_and_mint<'ctx, 'info>(
|
||||||
|
vaa: &'ctx AccountInfo<'info>,
|
||||||
|
cctp_ctx: CpiContext<
|
||||||
|
'_,
|
||||||
|
'_,
|
||||||
|
'_,
|
||||||
|
'info,
|
||||||
|
message_transmitter_program::cpi::ReceiveTokenMessengerMinterMessage<'info>,
|
||||||
|
>,
|
||||||
|
args: message_transmitter_program::cpi::ReceiveMessageArgs,
|
||||||
|
) -> Result<VaaAccount<'ctx>> {
|
||||||
|
// This is a very important check. We need to make sure that the VAA account is owned by the
|
||||||
|
// Wormhole Core Bridge program. Otherwise, an attacker can create a fake VAA account.
|
||||||
|
require_keys_eq!(
|
||||||
|
*vaa.owner,
|
||||||
|
wormhole_core_bridge_solana::sdk::id(),
|
||||||
|
ErrorCode::ConstraintOwner
|
||||||
|
);
|
||||||
|
|
||||||
|
let vaa = VaaAccount::load(vaa)?;
|
||||||
|
|
||||||
|
verify_vaa_and_mint_unchecked(&vaa, cctp_ctx, args)?;
|
||||||
|
|
||||||
// Finally return the VAA account reader.
|
// Finally return the VAA account reader.
|
||||||
Ok(vaa)
|
Ok(vaa)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::wormhole::core_bridge_program::Commitment;
|
use crate::wormhole::core_bridge_program::Commitment;
|
||||||
use anchor_lang::{prelude::*, system_program};
|
use anchor_lang::{prelude::*, system_program};
|
||||||
|
use wormhole_core_bridge_solana::state::Config;
|
||||||
|
|
||||||
#[derive(Accounts)]
|
#[derive(Accounts)]
|
||||||
pub struct PostMessage<'info> {
|
pub struct PostMessage<'info> {
|
||||||
|
@ -50,7 +51,7 @@ pub fn post_message<'info>(
|
||||||
// Pay Wormhole message fee.
|
// Pay Wormhole message fee.
|
||||||
{
|
{
|
||||||
let mut data: &[_] = &ctx.accounts.config.try_borrow_data()?;
|
let mut data: &[_] = &ctx.accounts.config.try_borrow_data()?;
|
||||||
let config = wormhole_core_bridge_solana::state::Config::deserialize(&mut data)?;
|
let Config { fee_lamports, .. } = Config::deserialize(&mut data)?;
|
||||||
|
|
||||||
system_program::transfer(
|
system_program::transfer(
|
||||||
CpiContext::new(
|
CpiContext::new(
|
||||||
|
@ -60,7 +61,7 @@ pub fn post_message<'info>(
|
||||||
to: ctx.accounts.fee_collector.to_account_info(),
|
to: ctx.accounts.fee_collector.to_account_info(),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
config.fee_lamports,
|
fee_lamports,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,9 @@ pub struct RedeemTokensWithPayload<'info> {
|
||||||
|
|
||||||
/// CHECK: Must be owned by the Wormhole Core Bridge program. This account will be read via
|
/// CHECK: Must be owned by the Wormhole Core Bridge program. This account will be read via
|
||||||
/// zero-copy using the [VaaAccount](core_bridge_program::sdk::VaaAccount) reader.
|
/// zero-copy using the [VaaAccount](core_bridge_program::sdk::VaaAccount) reader.
|
||||||
#[account(owner = core_bridge_program::id())]
|
///
|
||||||
|
/// NOTE: The owner of this account is checked in
|
||||||
|
/// [verify_vaa_and_mint](wormhole_cctp_solana::cpi::verify_vaa_and_mint).
|
||||||
vaa: AccountInfo<'info>,
|
vaa: AccountInfo<'info>,
|
||||||
|
|
||||||
/// Account representing that a VAA has been consumed.
|
/// Account representing that a VAA has been consumed.
|
||||||
|
|
|
@ -225,7 +225,7 @@ pub fn transfer_tokens_with_payload(
|
||||||
&[custodian_seeds],
|
&[custodian_seeds],
|
||||||
),
|
),
|
||||||
wormhole_cctp_solana::cpi::BurnAndPublishArgs {
|
wormhole_cctp_solana::cpi::BurnAndPublishArgs {
|
||||||
burn_source: ctx.accounts.burn_source.key(),
|
burn_source: Some(ctx.accounts.burn_source.key()),
|
||||||
destination_caller: ctx.accounts.registered_emitter.address,
|
destination_caller: ctx.accounts.registered_emitter.address,
|
||||||
destination_cctp_domain: ctx.accounts.registered_emitter.cctp_domain,
|
destination_cctp_domain: ctx.accounts.registered_emitter.cctp_domain,
|
||||||
amount,
|
amount,
|
||||||
|
|
Loading…
Reference in New Issue