diff --git a/cross-chain/solana/programs/tbtc/src/lib.rs b/cross-chain/solana/programs/tbtc/src/lib.rs index f2604b0f9..8011c6cc2 100644 --- a/cross-chain/solana/programs/tbtc/src/lib.rs +++ b/cross-chain/solana/programs/tbtc/src/lib.rs @@ -5,6 +5,8 @@ pub use constants::*; pub mod error; +pub(crate) mod event; + mod processor; pub(crate) use processor::*; diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/add_guardian.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/add_guardian.rs index 34bd26417..6cc51c2f6 100644 --- a/cross-chain/solana/programs/tbtc/src/processor/admin/add_guardian.rs +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/add_guardian.rs @@ -58,5 +58,7 @@ pub fn add_guardian(ctx: Context) -> Result<()> { // Update config. ctx.accounts.config.num_guardians += 1; + emit!(crate::event::GuardianAdded { guardian }); + Ok(()) } diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/add_minter.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/add_minter.rs index c107bd3ae..a76cf2480 100644 --- a/cross-chain/solana/programs/tbtc/src/processor/admin/add_minter.rs +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/add_minter.rs @@ -56,5 +56,8 @@ pub fn add_minter(ctx: Context) -> Result<()> { // Update config. ctx.accounts.config.num_minters += 1; + + emit!(crate::event::MinterAdded { minter }); + Ok(()) } diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/remove_guardian.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/remove_guardian.rs index 8642d9222..cd3bbe301 100644 --- a/cross-chain/solana/programs/tbtc/src/processor/admin/remove_guardian.rs +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/remove_guardian.rs @@ -42,10 +42,8 @@ pub struct RemoveGuardian<'info> { pub fn remove_guardian(ctx: Context) -> Result<()> { let guardians: &mut Vec<_> = &mut ctx.accounts.guardians; - match guardians - .iter() - .position(|&guardian| guardian == ctx.accounts.guardian.key()) - { + let removed = ctx.accounts.guardian.key(); + match guardians.iter().position(|&guardian| guardian == removed) { Some(index) => { // Remove pubkey to guardians account. guardians.swap_remove(index); @@ -53,6 +51,8 @@ pub fn remove_guardian(ctx: Context) -> Result<()> { // Update config. ctx.accounts.config.num_guardians -= 1; + emit!(crate::event::GuardianRemoved { guardian: removed }); + Ok(()) } None => err!(TbtcError::GuardianNonexistent), diff --git a/cross-chain/solana/programs/tbtc/src/processor/admin/remove_minter.rs b/cross-chain/solana/programs/tbtc/src/processor/admin/remove_minter.rs index 202f1ef42..6f6eeaf50 100644 --- a/cross-chain/solana/programs/tbtc/src/processor/admin/remove_minter.rs +++ b/cross-chain/solana/programs/tbtc/src/processor/admin/remove_minter.rs @@ -44,10 +44,8 @@ pub struct RemoveMinter<'info> { pub fn remove_minter(ctx: Context) -> Result<()> { let minters: &mut Vec<_> = &mut ctx.accounts.minters; - match minters - .iter() - .position(|&minter| minter == ctx.accounts.minter.key()) - { + let removed = ctx.accounts.minter.key(); + match minters.iter().position(|&minter| minter == removed) { Some(index) => { // Remove pubkey to minters account. minters.swap_remove(index); @@ -55,6 +53,8 @@ pub fn remove_minter(ctx: Context) -> Result<()> { // Update config. ctx.accounts.config.num_minters -= 1; + emit!(crate::event::MinterRemoved { minter: removed }); + Ok(()) } None => err!(TbtcError::GuardianNonexistent), diff --git a/cross-chain/solana/programs/wormhole-gateway/src/event.rs b/cross-chain/solana/programs/wormhole-gateway/src/event.rs new file mode 100644 index 000000000..17a57b7f7 --- /dev/null +++ b/cross-chain/solana/programs/wormhole-gateway/src/event.rs @@ -0,0 +1,34 @@ +use anchor_lang::prelude::*; + +#[event] +pub struct WormholeTbtcReceived { + pub receiver: Pubkey, + pub amount: u64, +} + +#[event] +pub struct WormholeTbtcSent { + pub amount: u64, + pub recipient_chain: u16, + pub gateway: [u8; 32], + pub recipient: [u8; 32], + pub arbiter_fee: u64, + pub nonce: u32, +} + +#[event] +pub struct WormholeTbtcDeposited { + pub depositor: Pubkey, + pub amount: u64, +} + +#[event] +pub struct GatewayAddressUpdated { + pub chain: u16, + pub gateway: [u8; 32], +} + +#[event] +pub struct MintingLimitUpdated { + pub minting_limit: u64, +} diff --git a/cross-chain/solana/programs/wormhole-gateway/src/lib.rs b/cross-chain/solana/programs/wormhole-gateway/src/lib.rs index 6d525a270..39b3fb5f9 100644 --- a/cross-chain/solana/programs/wormhole-gateway/src/lib.rs +++ b/cross-chain/solana/programs/wormhole-gateway/src/lib.rs @@ -4,6 +4,8 @@ pub mod constants; pub mod error; +pub(crate) mod event; + mod processor; pub(crate) use processor::*; diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/receive_tbtc.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/receive_tbtc.rs index 49187710e..b23269187 100644 --- a/cross-chain/solana/programs/wormhole-gateway/src/processor/receive_tbtc.rs +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/receive_tbtc.rs @@ -182,6 +182,12 @@ pub fn receive_tbtc(ctx: Context, _message_hash: [u8; 32]) -> Resul // Because we are working with wrapped token amounts, we can take the amount as-is and determine // whether to mint or transfer based on the minting limit. let amount = ctx.accounts.posted_vaa.data().amount(); + let recipient = &ctx.accounts.recipient; + + emit!(crate::event::WormholeTbtcReceived { + receiver: recipient.key(), + amount + }); let updated_minted_amount = ctx.accounts.custodian.minted_amount.saturating_add(amount); let custodian_seeds = &[Custodian::SEED_PREFIX, &[ctx.accounts.custodian.bump]]; @@ -198,7 +204,7 @@ pub fn receive_tbtc(ctx: Context, _message_hash: [u8; 32]) -> Resul associated_token::Create { payer: ctx.accounts.payer.to_account_info(), associated_token: ata.to_account_info(), - authority: ctx.accounts.recipient.to_account_info(), + authority: recipient.to_account_info(), mint: wrapped_tbtc_mint.to_account_info(), token_program: ctx.accounts.token_program.to_account_info(), system_program: ctx.accounts.system_program.to_account_info(), diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/gateway.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/gateway.rs index 8e81142af..acbd4346c 100644 --- a/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/gateway.rs +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/gateway.rs @@ -139,6 +139,17 @@ pub fn send_tbtc_gateway(ctx: Context, args: SendTbtcGatewayArg amount, )?; + let gateway = ctx.accounts.gateway_info.address; + + emit!(crate::event::WormholeTbtcSent { + amount, + recipient_chain, + gateway, + recipient, + arbiter_fee: Default::default(), + nonce + }); + let custodian = &ctx.accounts.custodian; // Finally transfer wrapped tBTC with the recipient encoded as this transfer's message. @@ -180,7 +191,7 @@ pub fn send_tbtc_gateway(ctx: Context, args: SendTbtcGatewayArg ), nonce, amount, - ctx.accounts.gateway_info.address, + gateway, recipient_chain, recipient.to_vec(), &crate::ID, diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/wrapped.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/wrapped.rs index f6d9ca734..0be9a0207 100644 --- a/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/wrapped.rs +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/send_tbtc/wrapped.rs @@ -129,6 +129,15 @@ pub fn send_tbtc_wrapped(ctx: Context, args: SendTbtcWrappedArg amount, )?; + emit!(crate::event::WormholeTbtcSent { + amount, + recipient_chain, + gateway: Default::default(), + recipient, + arbiter_fee, + nonce + }); + let custodian = &ctx.accounts.custodian; // Because the wormhole-anchor-sdk does not support relayable transfers (i.e. payload ID == 1), diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/update_gateway_address.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/update_gateway_address.rs index 6fcfbfed2..7b62dd521 100644 --- a/cross-chain/solana/programs/wormhole-gateway/src/processor/update_gateway_address.rs +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/update_gateway_address.rs @@ -39,12 +39,17 @@ pub fn update_gateway_address( ctx: Context, args: UpdateGatewayAddressArgs, ) -> Result<()> { - let UpdateGatewayAddressArgs { address, .. } = args; + let UpdateGatewayAddressArgs { chain, address } = args; ctx.accounts.gateway_info.set_inner(GatewayInfo { bump: ctx.bumps["gateway_info"], address, }); + emit!(crate::event::GatewayAddressUpdated { + chain, + gateway: address + }); + Ok(()) } diff --git a/cross-chain/solana/programs/wormhole-gateway/src/processor/update_minting_limit.rs b/cross-chain/solana/programs/wormhole-gateway/src/processor/update_minting_limit.rs index b52b72df4..c86bc4194 100644 --- a/cross-chain/solana/programs/wormhole-gateway/src/processor/update_minting_limit.rs +++ b/cross-chain/solana/programs/wormhole-gateway/src/processor/update_minting_limit.rs @@ -16,5 +16,10 @@ pub struct UpdateMintingLimit<'info> { pub fn update_minting_limit(ctx: Context, new_limit: u64) -> Result<()> { ctx.accounts.custodian.minting_limit = new_limit; + + emit!(crate::event::MintingLimitUpdated { + minting_limit: new_limit + }); + Ok(()) }