Derive Wrapped Mint/Tokens
Change-Id: Ic530013e1932daef382cd89b9f14d1069c4006b0
This commit is contained in:
parent
108a4a2ff9
commit
0a669111dd
|
@ -2,6 +2,7 @@ use solitaire::*;
|
|||
|
||||
use solana_program::{
|
||||
program::invoke_signed,
|
||||
pubkey::Pubkey,
|
||||
sysvar::{
|
||||
clock::Clock,
|
||||
rent::Rent,
|
||||
|
@ -20,6 +21,7 @@ use crate::{
|
|||
},
|
||||
error::Error::{
|
||||
InvalidFeeRecipient,
|
||||
InvalidGovernanceKey,
|
||||
InvalidGovernanceWithdrawal,
|
||||
InvalidGuardianSetUpgrade,
|
||||
},
|
||||
|
@ -30,8 +32,27 @@ use crate::{
|
|||
GovernancePayloadUpgrade,
|
||||
},
|
||||
vaa::ClaimableVAA,
|
||||
DeserializePayload,
|
||||
CHAIN_ID_SOLANA,
|
||||
};
|
||||
|
||||
fn verify_governance<'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)]
|
||||
pub struct UpgradeContract<'b> {
|
||||
/// Payer for account creation (vaa-claim)
|
||||
|
@ -76,6 +97,7 @@ pub fn upgrade_contract(
|
|||
accs: &mut UpgradeContract,
|
||||
_data: UpgradeContractData,
|
||||
) -> Result<()> {
|
||||
verify_governance(&accs.vaa)?;
|
||||
accs.vaa.verify(ctx.program_id)?;
|
||||
accs.vaa.claim(ctx, accs.payer.key)?;
|
||||
|
||||
|
@ -135,6 +157,7 @@ pub fn upgrade_guardian_set(
|
|||
return Err(InvalidGuardianSetUpgrade.into());
|
||||
}
|
||||
|
||||
verify_governance(&accs.vaa)?;
|
||||
accs.vaa.verify(ctx.program_id)?;
|
||||
accs.guardian_set_old.verify_derivation(
|
||||
ctx.program_id,
|
||||
|
@ -196,6 +219,7 @@ impl<'b> InstructionContext<'b> for SetFees<'b> {
|
|||
pub struct SetFeesData {}
|
||||
|
||||
pub fn set_fees(ctx: &ExecutionContext, accs: &mut SetFees, _data: SetFeesData) -> Result<()> {
|
||||
verify_governance(&accs.vaa)?;
|
||||
accs.vaa.verify(ctx.program_id)?;
|
||||
accs.vaa.claim(ctx, accs.payer.key)?;
|
||||
accs.bridge.config.fee = accs.vaa.fee.as_u64();
|
||||
|
@ -240,6 +264,7 @@ pub fn transfer_fees(
|
|||
return Err(InvalidFeeRecipient.into());
|
||||
}
|
||||
|
||||
verify_governance(&accs.vaa)?;
|
||||
accs.vaa.verify(ctx.program_id)?;
|
||||
|
||||
if accs
|
||||
|
|
|
@ -6,7 +6,6 @@ use crate::{
|
|||
error::Error::{
|
||||
InvalidGovernanceAction,
|
||||
InvalidGovernanceChain,
|
||||
InvalidGovernanceKey,
|
||||
InvalidGovernanceModule,
|
||||
VAAAlreadyExecuted,
|
||||
},
|
||||
|
@ -162,20 +161,6 @@ impl<'b, T: DeserializePayload> ClaimableVAA<'b, T> {
|
|||
pub fn verify(&self, program_id: &Pubkey) -> Result<()> {
|
||||
trace!("Seq: {}", self.message.meta().sequence);
|
||||
|
||||
// Do the Posted Message verification
|
||||
let (expected_emitter, current_emitter) = (
|
||||
std::env!("EMITTER_ADDRESS"),
|
||||
format!(
|
||||
"{}",
|
||||
Pubkey::new_from_array(self.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 || self.message.meta().emitter_chain != CHAIN_ID_SOLANA {
|
||||
return Err(InvalidGovernanceKey.into());
|
||||
}
|
||||
|
||||
// Verify that the claim account is derived correctly
|
||||
self.claim.verify_derivation(
|
||||
program_id,
|
||||
|
|
|
@ -54,14 +54,17 @@ impl<'b, const State: AccountState> Seeded<&WrappedDerivationData> for WrappedMi
|
|||
|
||||
pub type WrappedTokenMeta<'b, const State: AccountState> = Data<'b, WrappedMeta, { State }>;
|
||||
|
||||
impl<'b, const State: AccountState> Seeded<&WrappedDerivationData>
|
||||
pub struct WrappedMetaDerivationData {
|
||||
pub mint_key: Pubkey,
|
||||
}
|
||||
|
||||
impl<'b, const State: AccountState> Seeded<&WrappedMetaDerivationData>
|
||||
for WrappedTokenMeta<'b, { State }>
|
||||
{
|
||||
fn seeds(data: &WrappedDerivationData) -> Vec<Vec<u8>> {
|
||||
fn seeds(data: &WrappedMetaDerivationData) -> Vec<Vec<u8>> {
|
||||
vec![
|
||||
String::from("meta").as_bytes().to_vec(),
|
||||
data.token_chain.to_be_bytes().to_vec(),
|
||||
data.token_address.to_vec(),
|
||||
data.mint_key.to_bytes().to_vec(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,14 +90,14 @@ pub fn complete_native(
|
|||
accs.custody.verify_derivation(ctx.program_id, &derivation_data)?;
|
||||
|
||||
// Verify mints
|
||||
if accs.mint.info().key != accs.to.info().key {
|
||||
if *accs.mint.info().key != accs.to.mint {
|
||||
return Err(InvalidMint.into());
|
||||
}
|
||||
if accs.mint.info().key != accs.custody.info().key {
|
||||
if *accs.mint.info().key != accs.custody.mint {
|
||||
return Err(InvalidMint.into());
|
||||
}
|
||||
if &accs.custody.owner != accs.custody_signer.key {
|
||||
return Err(InvalidMint.into());
|
||||
if *accs.custody_signer.key != accs.custody.owner {
|
||||
return Err(WrongAccountOwner.into());
|
||||
}
|
||||
|
||||
// Verify VAA
|
||||
|
@ -109,6 +109,7 @@ pub fn complete_native(
|
|||
}
|
||||
|
||||
// Prevent vaa double signing
|
||||
accs.vaa.verify(ctx.program_id)?;
|
||||
accs.vaa.claim(ctx, accs.payer.key)?;
|
||||
|
||||
let mut amount = accs.vaa.amount.as_u64();
|
||||
|
@ -189,10 +190,11 @@ pub fn complete_wrapped(
|
|||
accs.mint.verify_derivation(ctx.program_id, &derivation_data)?;
|
||||
|
||||
// Verify mints
|
||||
if accs.mint.info().key != accs.to.info().key {
|
||||
if *accs.mint.info().key != accs.to.mint {
|
||||
return Err(InvalidMint.into());
|
||||
}
|
||||
|
||||
accs.vaa.verify(ctx.program_id)?;
|
||||
accs.vaa.claim(ctx, accs.payer.key)?;
|
||||
|
||||
// Mint tokens
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::{
|
|||
Endpoint,
|
||||
EndpointDerivationData,
|
||||
MintSigner,
|
||||
WrappedMetaDerivationData,
|
||||
WrappedDerivationData,
|
||||
WrappedMint,
|
||||
WrappedTokenMeta,
|
||||
|
@ -71,6 +72,14 @@ impl<'a> From<&CreateWrapped<'a>> for WrappedDerivationData {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&CreateWrapped<'a>> for WrappedMetaDerivationData {
|
||||
fn from(accs: &CreateWrapped<'a>) -> Self {
|
||||
WrappedMetaDerivationData {
|
||||
mint_key: *accs.mint.info().key,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> InstructionContext<'b> for CreateWrapped<'b> {
|
||||
}
|
||||
|
||||
|
@ -84,11 +93,14 @@ pub fn create_wrapped(
|
|||
) -> Result<()> {
|
||||
let derivation_data: WrappedDerivationData = (&*accs).into();
|
||||
accs.mint.verify_derivation(ctx.program_id, &derivation_data)?;
|
||||
accs.meta.verify_derivation(ctx.program_id, &derivation_data)?;
|
||||
|
||||
let meta_derivation_data: WrappedMetaDerivationData = (&*accs).into();
|
||||
accs.meta.verify_derivation(ctx.program_id, &meta_derivation_data)?;
|
||||
|
||||
let derivation_data: EndpointDerivationData = (&*accs).into();
|
||||
accs.chain_registration.verify_derivation(ctx.program_id, &derivation_data)?;
|
||||
|
||||
accs.vaa.verify(ctx.program_id)?;
|
||||
accs.vaa.claim(ctx, accs.payer.key)?;
|
||||
|
||||
// Create mint account
|
||||
|
|
|
@ -40,7 +40,7 @@ use std::ops::{
|
|||
};
|
||||
|
||||
// Confirm that a ClaimableVAA came from the correct chain, signed by the right emitter.
|
||||
fn verify_claim<'a, T>(vaa: &ClaimableVAA<'a, T>) -> Result<()>
|
||||
fn verify_governance<'a, T>(vaa: &ClaimableVAA<'a, T>) -> Result<()>
|
||||
where
|
||||
T: DeserializePayload,
|
||||
{
|
||||
|
@ -49,7 +49,6 @@ where
|
|||
"{}",
|
||||
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())
|
||||
|
@ -99,7 +98,8 @@ pub fn upgrade_contract(
|
|||
accs: &mut UpgradeContract,
|
||||
_data: UpgradeContractData,
|
||||
) -> Result<()> {
|
||||
verify_claim(&accs.vaa)?;
|
||||
verify_governance(&accs.vaa);
|
||||
accs.vaa.verify(&ctx.program_id)?;
|
||||
|
||||
accs.vaa.claim(ctx, accs.payer.key)?;
|
||||
|
||||
|
@ -154,6 +154,8 @@ pub fn register_chain(
|
|||
accs.endpoint.verify_derivation(ctx.program_id, &derivation_data)?;
|
||||
|
||||
// Claim VAA
|
||||
verify_governance(&accs.vaa);
|
||||
accs.vaa.verify(&ctx.program_id)?;
|
||||
accs.vaa.claim(ctx, accs.payer.key)?;
|
||||
|
||||
// Create endpoint
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::{
|
|||
EmitterAccount,
|
||||
MintSigner,
|
||||
WrappedDerivationData,
|
||||
WrappedMetaDerivationData,
|
||||
WrappedMint,
|
||||
WrappedTokenMeta,
|
||||
},
|
||||
|
@ -123,10 +124,11 @@ pub fn transfer_native(
|
|||
) -> Result<()> {
|
||||
// Verify that the custody account is derived correctly
|
||||
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
|
||||
if accs.mint.info().key != accs.from.info().key {
|
||||
if accs.from.mint != *accs.mint.info().key {
|
||||
return Err(TokenBridgeError::InvalidMint.into());
|
||||
}
|
||||
|
||||
|
@ -243,6 +245,14 @@ impl<'a> From<&TransferWrapped<'a>> for WrappedDerivationData {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&TransferWrapped<'a>> for WrappedMetaDerivationData {
|
||||
fn from(accs: &TransferWrapped<'a>) -> Self {
|
||||
WrappedMetaDerivationData {
|
||||
mint_key: *accs.mint.info().key,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> InstructionContext<'b> for TransferWrapped<'b> {
|
||||
}
|
||||
|
||||
|
@ -271,8 +281,11 @@ pub fn transfer_wrapped(
|
|||
}
|
||||
|
||||
// Verify that meta is correct
|
||||
accs.wrapped_meta
|
||||
.verify_derivation(ctx.program_id, &(&*accs).into())?;
|
||||
let derivation_data: WrappedMetaDerivationData = (&*accs).into();
|
||||
accs.wrapped_meta.verify_derivation(
|
||||
ctx.program_id,
|
||||
&derivation_data,
|
||||
)?;
|
||||
|
||||
// Burn tokens
|
||||
let burn_ix = spl_token::instruction::burn(
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::{
|
|||
EndpointDerivationData,
|
||||
MintSigner,
|
||||
WrappedDerivationData,
|
||||
WrappedMetaDerivationData,
|
||||
WrappedMint,
|
||||
WrappedTokenMeta,
|
||||
},
|
||||
|
@ -215,9 +216,8 @@ pub fn create_wrapped(
|
|||
&program_id,
|
||||
);
|
||||
let mint_meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
|
||||
&WrappedDerivationData {
|
||||
token_chain: payload.token_chain,
|
||||
token_address: payload.token_address,
|
||||
&WrappedMetaDerivationData {
|
||||
mint_key,
|
||||
},
|
||||
&program_id,
|
||||
);
|
||||
|
@ -395,9 +395,8 @@ pub fn transfer_wrapped(
|
|||
&program_id,
|
||||
);
|
||||
let wrapped_meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
|
||||
&WrappedDerivationData {
|
||||
token_chain,
|
||||
token_address,
|
||||
&WrappedMetaDerivationData {
|
||||
mint_key: wrapped_mint_key,
|
||||
},
|
||||
&program_id,
|
||||
);
|
||||
|
|
|
@ -381,7 +381,7 @@ mod helpers {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn complete_transfer_native(
|
||||
pub fn complete_native(
|
||||
client: &RpcClient,
|
||||
program: &Pubkey,
|
||||
bridge: &Pubkey,
|
||||
|
|
|
@ -293,7 +293,7 @@ fn test_transfer_native(context: &mut Context) -> () {
|
|||
}
|
||||
|
||||
fn test_transfer_wrapped(context: &mut Context, token_account: Pubkey) -> () {
|
||||
println!("Transfer Wrapped");
|
||||
println!("TransferWrapped");
|
||||
use token_bridge::{
|
||||
accounts::ConfigAccount,
|
||||
types::Config,
|
||||
|
@ -401,7 +401,7 @@ fn test_transfer_native_in(context: &mut Context) -> () {
|
|||
let (vaa, _, _) = common::generate_vaa([0u8; 32], 2, message, nonce, 1);
|
||||
let message_key = common::post_vaa(client, bridge, payer, vaa.clone()).unwrap();
|
||||
|
||||
common::complete_transfer_native(
|
||||
common::complete_native(
|
||||
client,
|
||||
token_bridge,
|
||||
bridge,
|
||||
|
@ -414,7 +414,7 @@ fn test_transfer_native_in(context: &mut Context) -> () {
|
|||
}
|
||||
|
||||
fn test_transfer_wrapped_in(context: &mut Context, to: Pubkey) -> () {
|
||||
println!("TransferWrapped");
|
||||
println!("TransferWrappedIn");
|
||||
use token_bridge::{
|
||||
accounts::ConfigAccount,
|
||||
types::Config,
|
||||
|
|
Loading…
Reference in New Issue