928 lines
23 KiB
Rust
928 lines
23 KiB
Rust
#![allow(warnings)]
|
|
|
|
use borsh::BorshSerialize;
|
|
use byteorder::{
|
|
BigEndian,
|
|
WriteBytesExt,
|
|
};
|
|
use hex_literal::hex;
|
|
use rand::Rng;
|
|
use secp256k1::{
|
|
Message as Secp256k1Message,
|
|
PublicKey,
|
|
SecretKey,
|
|
};
|
|
use sha3::Digest;
|
|
use solana_client::rpc_client::RpcClient;
|
|
use solana_program::{
|
|
borsh::try_from_slice_unchecked,
|
|
hash,
|
|
instruction::{
|
|
AccountMeta,
|
|
Instruction,
|
|
},
|
|
program_pack::Pack,
|
|
pubkey::Pubkey,
|
|
system_instruction::{
|
|
self,
|
|
create_account,
|
|
},
|
|
system_program,
|
|
sysvar,
|
|
};
|
|
use solana_sdk::{
|
|
commitment_config::CommitmentConfig,
|
|
signature::{
|
|
read_keypair_file,
|
|
Keypair,
|
|
Signer,
|
|
},
|
|
transaction::Transaction,
|
|
};
|
|
use solitaire::{
|
|
processors::seeded::Seeded,
|
|
AccountState,
|
|
};
|
|
use spl_token::state::Mint;
|
|
use std::{
|
|
convert::TryInto,
|
|
io::{
|
|
Cursor,
|
|
Write,
|
|
},
|
|
time::{
|
|
Duration,
|
|
SystemTime,
|
|
},
|
|
};
|
|
|
|
use bridge::{
|
|
accounts::{
|
|
Bridge,
|
|
FeeCollector,
|
|
GuardianSet,
|
|
GuardianSetDerivationData,
|
|
PostedVAA,
|
|
PostedVAADerivationData,
|
|
SignatureSet,
|
|
},
|
|
instruction,
|
|
types::{
|
|
BridgeConfig,
|
|
BridgeData,
|
|
GovernancePayloadGuardianSetChange,
|
|
GovernancePayloadSetMessageFee,
|
|
GovernancePayloadTransferFees,
|
|
GuardianSetData,
|
|
MessageData,
|
|
PostedVAAData,
|
|
SequenceTracker,
|
|
SignatureSet as SignatureSetData,
|
|
},
|
|
Initialize,
|
|
PostVAA,
|
|
PostVAAData,
|
|
SerializePayload,
|
|
DeserializePayload,
|
|
Signature,
|
|
};
|
|
use primitive_types::U256;
|
|
use std::{
|
|
collections::HashMap,
|
|
str::FromStr,
|
|
time::UNIX_EPOCH,
|
|
};
|
|
use token_bridge::{
|
|
accounts::{
|
|
EmitterAccount,
|
|
MintSigner,
|
|
WrappedDerivationData,
|
|
WrappedMint,
|
|
},
|
|
api::EXTERNAL_MINTS,
|
|
messages::{
|
|
PayloadAssetMeta,
|
|
PayloadGovernanceRegisterChain,
|
|
PayloadTransfer,
|
|
},
|
|
types::Address,
|
|
};
|
|
|
|
mod common;
|
|
|
|
const GOVERNANCE_KEY: [u8; 64] = [
|
|
240, 133, 120, 113, 30, 67, 38, 184, 197, 72, 234, 99, 241, 21, 58, 225, 41, 157, 171, 44, 196,
|
|
163, 134, 236, 92, 148, 110, 68, 127, 114, 177, 0, 173, 253, 199, 9, 242, 142, 201, 174, 108,
|
|
197, 18, 102, 115, 0, 31, 205, 127, 188, 191, 56, 171, 228, 20, 247, 149, 170, 141, 231, 147,
|
|
88, 97, 199,
|
|
];
|
|
|
|
struct Context {
|
|
/// Address of the core bridge contract.
|
|
bridge: Pubkey,
|
|
|
|
/// Shared RPC client for tests to make transactions with.
|
|
client: RpcClient,
|
|
|
|
/// Payer key with a ton of lamports to ease testing with.
|
|
payer: Keypair,
|
|
|
|
/// Track nonces throughout the tests.
|
|
seq: Sequencer,
|
|
|
|
/// Address of the token bridge itself that we wish to test.
|
|
token_bridge: Pubkey,
|
|
|
|
/// Keypairs for mint information, required in multiple tests.
|
|
mint_authority: Keypair,
|
|
mint: Keypair,
|
|
mint_meta: Pubkey,
|
|
|
|
/// Keypairs for test token accounts.
|
|
token_authority: Keypair,
|
|
token_account: Keypair,
|
|
external_token_account: Keypair,
|
|
metadata_account: Pubkey,
|
|
}
|
|
|
|
/// Small helper to track and provide sequences during tests. This is in particular needed for
|
|
/// guardian operations that require them for derivations.
|
|
struct Sequencer {
|
|
sequences: HashMap<[u8; 32], u64>,
|
|
}
|
|
|
|
impl Sequencer {
|
|
fn next(&mut self, emitter: [u8; 32]) -> u64 {
|
|
let entry = self.sequences.entry(emitter).or_insert(0);
|
|
*entry += 1;
|
|
*entry - 1
|
|
}
|
|
|
|
fn peek(&mut self, emitter: [u8; 32]) -> u64 {
|
|
*self.sequences.entry(emitter).or_insert(0)
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn run_integration_tests() {
|
|
let (payer, client, bridge, token_bridge) = common::setup();
|
|
|
|
// Setup a Bridge to test against.
|
|
println!("Bridge: {}", bridge);
|
|
common::initialize_bridge(&client, &bridge, &payer);
|
|
|
|
// Context for test environment.
|
|
let mint = Keypair::new();
|
|
let mint_pubkey = mint.pubkey();
|
|
let metadata_pubkey = Pubkey::from_str("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s").unwrap();
|
|
|
|
// SPL Token Meta
|
|
let metadata_seeds = &[
|
|
"metadata".as_bytes(),
|
|
metadata_pubkey.as_ref(),
|
|
mint_pubkey.as_ref(),
|
|
];
|
|
|
|
let (metadata_key, metadata_bump_seed) = Pubkey::find_program_address(
|
|
metadata_seeds,
|
|
&Pubkey::from_str("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s").unwrap(),
|
|
);
|
|
|
|
// Token Bridge Meta
|
|
use token_bridge::accounts::WrappedTokenMeta;
|
|
let metadata_account = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
|
|
&token_bridge::accounts::WrappedMetaDerivationData {
|
|
mint_key: mint_pubkey.clone(),
|
|
},
|
|
&token_bridge,
|
|
);
|
|
|
|
let mut context = Context {
|
|
seq: Sequencer {
|
|
sequences: HashMap::new(),
|
|
},
|
|
bridge,
|
|
client,
|
|
payer,
|
|
token_bridge,
|
|
mint_authority: Keypair::new(),
|
|
mint,
|
|
mint_meta: metadata_account,
|
|
token_account: Keypair::new(),
|
|
external_token_account: Keypair::new(),
|
|
token_authority: Keypair::new(),
|
|
metadata_account: metadata_key,
|
|
};
|
|
|
|
// Create a mint for use within tests.
|
|
common::create_mint(
|
|
&context.client,
|
|
&context.payer,
|
|
&context.mint_authority.pubkey(),
|
|
&context.mint,
|
|
)
|
|
.unwrap();
|
|
|
|
// Create Token accounts for use within tests.
|
|
common::create_token_account(
|
|
&context.client,
|
|
&context.payer,
|
|
&context.token_account,
|
|
context.token_authority.pubkey(),
|
|
context.mint.pubkey(),
|
|
)
|
|
.unwrap();
|
|
|
|
// Mint tokens
|
|
common::mint_tokens(
|
|
&context.client,
|
|
&context.payer,
|
|
&context.mint_authority,
|
|
&context.mint,
|
|
&context.token_account.pubkey(),
|
|
1000,
|
|
)
|
|
.unwrap();
|
|
|
|
// Initialize the bridge and verify the bridges state.
|
|
test_initialize(&mut context);
|
|
test_transfer_native(&mut context);
|
|
test_attest(&mut context);
|
|
test_register_chain(&mut context);
|
|
test_transfer_native_in(&mut context);
|
|
|
|
// Create an SPL Metadata account to test attestations for wrapped tokens.
|
|
common::create_spl_metadata(
|
|
&context.client,
|
|
&context.payer,
|
|
&context.metadata_account,
|
|
&context.mint_authority,
|
|
&context.mint,
|
|
&context.payer.pubkey(),
|
|
"BTC".to_string(),
|
|
"Bitcoin".to_string(),
|
|
)
|
|
.unwrap();
|
|
|
|
let wrapped = test_create_wrapped(&mut context);
|
|
let wrapped_acc = Keypair::new();
|
|
common::create_token_account(
|
|
&context.client,
|
|
&context.payer,
|
|
&wrapped_acc,
|
|
context.token_authority.pubkey(),
|
|
wrapped,
|
|
)
|
|
.unwrap();
|
|
test_transfer_wrapped_in(&mut context, wrapped_acc.pubkey());
|
|
test_transfer_wrapped(&mut context, wrapped_acc.pubkey());
|
|
|
|
// Sollet specific tests
|
|
test_create_wrapped_preexisting(&mut context);
|
|
test_transfer_in_wrapped_preexisting(&mut context);
|
|
test_transfer_in_wrapped_preexisting_invalid(&mut context);
|
|
test_transfer_wrapped_preexisting(&mut context);
|
|
}
|
|
|
|
fn test_attest(context: &mut Context) -> () {
|
|
println!("Attest");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
ref mint_authority,
|
|
ref mint,
|
|
ref mint_meta,
|
|
ref metadata_account,
|
|
..
|
|
} = context;
|
|
|
|
let message = &Keypair::new();
|
|
|
|
common::attest(
|
|
client,
|
|
token_bridge,
|
|
bridge,
|
|
payer,
|
|
message,
|
|
mint.pubkey(),
|
|
0,
|
|
)
|
|
.unwrap();
|
|
|
|
let emitter_key = EmitterAccount::key(None, &token_bridge);
|
|
let mint_data = Mint::unpack(
|
|
&client
|
|
.get_account_with_commitment(&mint.pubkey(), CommitmentConfig::processed())
|
|
.unwrap()
|
|
.value
|
|
.unwrap()
|
|
.data,
|
|
)
|
|
.unwrap();
|
|
let payload = PayloadAssetMeta {
|
|
token_address: mint.pubkey().to_bytes(),
|
|
token_chain: 1,
|
|
decimals: mint_data.decimals,
|
|
symbol: "USD".to_string(),
|
|
name: "Bitcoin".to_string(),
|
|
};
|
|
let payload = payload.try_to_vec().unwrap();
|
|
}
|
|
|
|
fn test_transfer_native(context: &mut Context) -> () {
|
|
println!("Transfer Native");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
ref mint_authority,
|
|
ref mint,
|
|
ref mint_meta,
|
|
ref token_account,
|
|
ref token_authority,
|
|
..
|
|
} = context;
|
|
|
|
let message = &Keypair::new();
|
|
|
|
common::transfer_native(
|
|
client,
|
|
token_bridge,
|
|
bridge,
|
|
payer,
|
|
message,
|
|
token_account,
|
|
token_authority,
|
|
mint.pubkey(),
|
|
100,
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
fn test_transfer_wrapped(context: &mut Context, token_account: Pubkey) -> () {
|
|
println!("TransferWrapped");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
ref mint_authority,
|
|
ref token_authority,
|
|
..
|
|
} = context;
|
|
|
|
let message = &Keypair::new();
|
|
|
|
common::transfer_wrapped(
|
|
client,
|
|
token_bridge,
|
|
bridge,
|
|
payer,
|
|
message,
|
|
token_account,
|
|
token_authority,
|
|
2,
|
|
[1u8; 32],
|
|
10000000,
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
fn test_register_chain(context: &mut Context) -> () {
|
|
println!("Register Chain");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
ref mint_authority,
|
|
ref mint,
|
|
ref mint_meta,
|
|
ref token_account,
|
|
ref token_authority,
|
|
..
|
|
} = context;
|
|
|
|
let nonce = rand::thread_rng().gen();
|
|
let emitter = Keypair::from_bytes(&GOVERNANCE_KEY).unwrap();
|
|
let payload = PayloadGovernanceRegisterChain {
|
|
chain: 2,
|
|
endpoint_address: [0u8; 32],
|
|
};
|
|
let message = payload.try_to_vec().unwrap();
|
|
|
|
let (vaa, _, _) = common::generate_vaa(emitter.pubkey().to_bytes(), 1, message, nonce, 0);
|
|
common::post_vaa(client, bridge, payer, vaa.clone()).unwrap();
|
|
|
|
let mut msg_derivation_data = &PostedVAADerivationData {
|
|
payload_hash: bridge::instructions::hash_vaa(&vaa).to_vec(),
|
|
};
|
|
let message_key =
|
|
PostedVAA::<'_, { AccountState::MaybeInitialized }>::key(&msg_derivation_data, &bridge);
|
|
|
|
common::register_chain(
|
|
client,
|
|
token_bridge,
|
|
bridge,
|
|
&message_key,
|
|
vaa,
|
|
payload,
|
|
payer,
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
fn test_transfer_native_in(context: &mut Context) -> () {
|
|
println!("TransferNativeIn");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
ref mint_authority,
|
|
ref mint,
|
|
ref mint_meta,
|
|
ref token_account,
|
|
ref token_authority,
|
|
..
|
|
} = context;
|
|
|
|
let nonce = rand::thread_rng().gen();
|
|
|
|
let payload = PayloadTransfer {
|
|
amount: U256::from(100),
|
|
token_address: mint.pubkey().to_bytes(),
|
|
token_chain: 1,
|
|
to: token_account.pubkey().to_bytes(),
|
|
to_chain: 1,
|
|
fee: U256::from(0),
|
|
};
|
|
let message = payload.try_to_vec().unwrap();
|
|
|
|
let (vaa, _, _) = common::generate_vaa([0u8; 32], 2, message, nonce, 1);
|
|
common::post_vaa(client, bridge, payer, vaa.clone()).unwrap();
|
|
let mut msg_derivation_data = &PostedVAADerivationData {
|
|
payload_hash: bridge::instructions::hash_vaa(&vaa).to_vec(),
|
|
};
|
|
let message_key =
|
|
PostedVAA::<'_, { AccountState::MaybeInitialized }>::key(&msg_derivation_data, &bridge);
|
|
|
|
common::complete_native(
|
|
client,
|
|
token_bridge,
|
|
bridge,
|
|
&message_key,
|
|
vaa,
|
|
payload,
|
|
payer,
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
fn test_transfer_wrapped_in(context: &mut Context, to: Pubkey) -> () {
|
|
println!("TransferWrappedIn");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
ref mint_authority,
|
|
ref mint,
|
|
ref mint_meta,
|
|
ref token_account,
|
|
ref token_authority,
|
|
..
|
|
} = context;
|
|
|
|
let nonce = rand::thread_rng().gen();
|
|
|
|
let payload = PayloadTransfer {
|
|
amount: U256::from(100000000),
|
|
token_address: [1u8; 32],
|
|
token_chain: 2,
|
|
to: to.to_bytes(),
|
|
to_chain: 1,
|
|
fee: U256::from(0),
|
|
};
|
|
let message = payload.try_to_vec().unwrap();
|
|
|
|
let (vaa, _, _) = common::generate_vaa([0u8; 32], 2, message, nonce, rand::thread_rng().gen());
|
|
common::post_vaa(client, bridge, payer, vaa.clone()).unwrap();
|
|
let mut msg_derivation_data = &PostedVAADerivationData {
|
|
payload_hash: bridge::instructions::hash_vaa(&vaa).to_vec(),
|
|
};
|
|
let message_key =
|
|
PostedVAA::<'_, { AccountState::MaybeInitialized }>::key(&msg_derivation_data, &bridge);
|
|
|
|
common::complete_transfer_wrapped(
|
|
client,
|
|
token_bridge,
|
|
bridge,
|
|
&message_key,
|
|
vaa,
|
|
payload,
|
|
payer,
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
fn test_create_wrapped(context: &mut Context) -> (Pubkey) {
|
|
println!("CreateWrapped");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
ref mint_authority,
|
|
ref mint,
|
|
ref mint_meta,
|
|
ref token_account,
|
|
ref token_authority,
|
|
..
|
|
} = context;
|
|
|
|
let nonce = rand::thread_rng().gen();
|
|
|
|
let payload = PayloadAssetMeta {
|
|
token_address: [1u8; 32],
|
|
token_chain: 2,
|
|
decimals: 7,
|
|
symbol: "".to_string(),
|
|
name: "".to_string(),
|
|
};
|
|
let message = payload.try_to_vec().unwrap();
|
|
|
|
let (vaa, _, _) = common::generate_vaa([0u8; 32], 2, message, nonce, 2);
|
|
common::post_vaa(client, bridge, payer, vaa.clone()).unwrap();
|
|
let mut msg_derivation_data = &PostedVAADerivationData {
|
|
payload_hash: bridge::instructions::hash_vaa(&vaa).to_vec(),
|
|
};
|
|
let message_key =
|
|
PostedVAA::<'_, { AccountState::MaybeInitialized }>::key(&msg_derivation_data, &bridge);
|
|
|
|
common::create_wrapped(
|
|
client,
|
|
token_bridge,
|
|
bridge,
|
|
&message_key,
|
|
vaa,
|
|
payload,
|
|
payer,
|
|
)
|
|
.unwrap();
|
|
|
|
return WrappedMint::<'_, { AccountState::Initialized }>::key(
|
|
&WrappedDerivationData {
|
|
token_chain: 2,
|
|
token_address: [1u8; 32],
|
|
},
|
|
token_bridge,
|
|
);
|
|
}
|
|
|
|
fn test_create_wrapped_preexisting(context: &mut Context) -> (Pubkey) {
|
|
println!("CreateWrappedPreexisting");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
ref mint_authority,
|
|
ref mint,
|
|
ref mint_meta,
|
|
ref token_account,
|
|
ref token_authority,
|
|
..
|
|
} = context;
|
|
|
|
// FDhdMYh3KsF64Jxzh8tnx9rJXQTcN461rguUK9z9zm64
|
|
let mint_keypair = Keypair::from_bytes(&[
|
|
78, 244, 23, 240, 92, 61, 31, 184, 188, 176, 28, 188, 143, 230, 185, 139, 23, 32, 60, 221,
|
|
166, 209, 15, 175, 243, 160, 174, 226, 190, 8, 124, 115, 211, 68, 134, 6, 252, 30, 9, 108,
|
|
54, 236, 74, 254, 5, 8, 178, 146, 14, 182, 243, 214, 1, 108, 184, 93, 66, 224, 100, 135,
|
|
16, 120, 69, 93,
|
|
])
|
|
.unwrap();
|
|
// Create a wrapped mint
|
|
common::create_mint(
|
|
client,
|
|
payer,
|
|
&MintSigner::key(None, token_bridge),
|
|
&mint_keypair,
|
|
);
|
|
|
|
let nonce = rand::thread_rng().gen();
|
|
println!("{}", hex::encode([0xaau8; 32]));
|
|
println!("{:?}", EXTERNAL_MINTS);
|
|
println!("{:?}", EXTERNAL_MINTS.get(hex::encode([0xaau8; 32]).as_str()));
|
|
|
|
let payload = PayloadAssetMeta {
|
|
token_address: [0xaau8; 32],
|
|
token_chain: 2,
|
|
decimals: 7,
|
|
symbol: "".to_string(),
|
|
name: "".to_string(),
|
|
};
|
|
let message = payload.try_to_vec().unwrap();
|
|
|
|
let (vaa, _, _) = common::generate_vaa([0u8; 32], 2, message, nonce, 120);
|
|
common::post_vaa(client, bridge, payer, vaa.clone()).unwrap();
|
|
let mut msg_derivation_data = &PostedVAADerivationData {
|
|
payload_hash: bridge::instructions::hash_vaa(&vaa).to_vec(),
|
|
};
|
|
let message_key =
|
|
PostedVAA::<'_, { AccountState::MaybeInitialized }>::key(&msg_derivation_data, &bridge);
|
|
|
|
common::create_wrapped(
|
|
client,
|
|
token_bridge,
|
|
bridge,
|
|
&message_key,
|
|
vaa,
|
|
payload,
|
|
payer,
|
|
)
|
|
.unwrap();
|
|
|
|
return WrappedMint::<'_, { AccountState::Initialized }>::key(
|
|
&WrappedDerivationData {
|
|
token_chain: 2,
|
|
token_address: [0xaau8; 32],
|
|
},
|
|
token_bridge,
|
|
);
|
|
}
|
|
|
|
fn test_initialize(context: &mut Context) {
|
|
println!("Initialize");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
..
|
|
} = context;
|
|
|
|
common::initialize(client, token_bridge, payer, &bridge).unwrap();
|
|
|
|
// Verify Token Bridge State
|
|
let config_key = ConfigAccount::<'_, { AccountState::Uninitialized }>::key(None, &token_bridge);
|
|
let config: Config = common::get_account_data(client, &config_key).unwrap();
|
|
assert_eq!(config.wormhole_bridge, *bridge);
|
|
}
|
|
|
|
fn test_transfer_in_wrapped_preexisting(context: &mut Context) {
|
|
println!("TransferInPreexisting");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
ref mint_authority,
|
|
ref mint,
|
|
ref mint_meta,
|
|
ref external_token_account,
|
|
ref token_authority,
|
|
..
|
|
} = context;
|
|
|
|
// FDhdMYh3KsF64Jxzh8tnx9rJXQTcN461rguUK9z9zm64
|
|
let mint_keypair = Keypair::from_bytes(&[
|
|
78, 244, 23, 240, 92, 61, 31, 184, 188, 176, 28, 188, 143, 230, 185, 139, 23, 32, 60, 221,
|
|
166, 209, 15, 175, 243, 160, 174, 226, 190, 8, 124, 115, 211, 68, 134, 6, 252, 30, 9, 108,
|
|
54, 236, 74, 254, 5, 8, 178, 146, 14, 182, 243, 214, 1, 108, 184, 93, 66, 224, 100, 135,
|
|
16, 120, 69, 93,
|
|
])
|
|
.unwrap();
|
|
|
|
// Create Token accounts for use within tests.
|
|
common::create_token_account(
|
|
&context.client,
|
|
&context.payer,
|
|
&external_token_account,
|
|
context.token_authority.pubkey(),
|
|
mint_keypair.pubkey(),
|
|
)
|
|
.unwrap();
|
|
|
|
let nonce = rand::thread_rng().gen();
|
|
let payload = PayloadTransfer {
|
|
amount: U256::from(10000),
|
|
token_address: [0xaau8; 32],
|
|
token_chain: 2,
|
|
to: external_token_account.pubkey().to_bytes(),
|
|
to_chain: 1,
|
|
fee: U256::from(0),
|
|
};
|
|
|
|
let message = payload.try_to_vec().unwrap();
|
|
let (vaa, _, _) = common::generate_vaa(
|
|
[0u8; 32],
|
|
2,
|
|
message,
|
|
nonce,
|
|
0
|
|
);
|
|
common::post_vaa(client, bridge, payer, vaa.clone()).unwrap();
|
|
|
|
let mut msg_derivation_data = &PostedVAADerivationData {
|
|
payload_hash: bridge::instructions::hash_vaa(&vaa).to_vec(),
|
|
};
|
|
let message_key =
|
|
PostedVAA::<'_, { AccountState::MaybeInitialized }>::key(&msg_derivation_data, &bridge);
|
|
|
|
common::complete_transfer_wrapped(
|
|
client,
|
|
token_bridge,
|
|
bridge,
|
|
&message_key,
|
|
vaa,
|
|
payload,
|
|
payer,
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
fn test_transfer_wrapped_preexisting(context: &mut Context) {
|
|
println!("TransferOutPreexisting");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
ref mint_authority,
|
|
ref mint,
|
|
ref mint_meta,
|
|
ref external_token_account,
|
|
ref token_authority,
|
|
..
|
|
} = context;
|
|
|
|
// FDhdMYh3KsF64Jxzh8tnx9rJXQTcN461rguUK9z9zm64
|
|
let mint_keypair = Keypair::from_bytes(&[
|
|
78, 244, 23, 240, 92, 61, 31, 184, 188, 176, 28, 188, 143, 230, 185, 139, 23, 32, 60, 221,
|
|
166, 209, 15, 175, 243, 160, 174, 226, 190, 8, 124, 115, 211, 68, 134, 6, 252, 30, 9, 108,
|
|
54, 236, 74, 254, 5, 8, 178, 146, 14, 182, 243, 214, 1, 108, 184, 93, 66, 224, 100, 135,
|
|
16, 120, 69, 93,
|
|
])
|
|
.unwrap();
|
|
|
|
let message = &Keypair::new();
|
|
|
|
common::transfer_wrapped(
|
|
client,
|
|
token_bridge,
|
|
bridge,
|
|
payer,
|
|
message,
|
|
external_token_account.pubkey(),
|
|
token_authority,
|
|
2,
|
|
[0xaau8; 32],
|
|
1000,
|
|
);
|
|
|
|
let account_data = Account::unpack(
|
|
&client
|
|
.get_account_with_commitment(&external_token_account.pubkey(), CommitmentConfig::processed())
|
|
.unwrap()
|
|
.value
|
|
.unwrap()
|
|
.data,
|
|
)
|
|
.unwrap();
|
|
|
|
// Check truncation for external asset shrinks by the correct amount.
|
|
assert_eq!(0, account_data.amount);
|
|
|
|
let posted_message: PostedVAAData = common::get_account_data(client, &message.pubkey()).unwrap();
|
|
let mut transfer = posted_message.0.payload.clone();
|
|
let transfer = &mut &transfer[0..];
|
|
let transfer: PayloadTransfer = PayloadTransfer::deserialize(transfer).unwrap();
|
|
assert_eq!(transfer.amount, U256::from(10000));
|
|
}
|
|
|
|
fn test_transfer_in_wrapped_preexisting_invalid(context: &mut Context) {
|
|
println!("TransferInPreexisting");
|
|
use token_bridge::{
|
|
accounts::ConfigAccount,
|
|
types::Config,
|
|
};
|
|
|
|
let Context {
|
|
ref payer,
|
|
ref client,
|
|
ref bridge,
|
|
ref token_bridge,
|
|
ref mint_authority,
|
|
ref mint,
|
|
ref mint_meta,
|
|
ref external_token_account,
|
|
ref token_authority,
|
|
..
|
|
} = context;
|
|
|
|
// FDhdMYh3KsF64Jxzh8tnx9rJXQTcN461rguUK9z9zm64
|
|
let mint_keypair = Keypair::from_bytes(&[
|
|
78, 244, 23, 240, 92, 61, 31, 184, 188, 176, 28, 188, 143, 230, 185, 139, 23, 32, 60, 221,
|
|
166, 209, 15, 175, 243, 160, 174, 226, 190, 8, 124, 115, 211, 68, 134, 6, 252, 30, 9, 108,
|
|
54, 236, 74, 254, 5, 8, 178, 146, 14, 182, 243, 214, 1, 108, 184, 93, 66, 224, 100, 135,
|
|
16, 120, 69, 93,
|
|
])
|
|
.unwrap();
|
|
|
|
let nonce = rand::thread_rng().gen();
|
|
let payload = PayloadTransfer {
|
|
amount: U256::from(10000),
|
|
token_address: [0xabu8; 32],
|
|
token_chain: 2,
|
|
to: external_token_account.pubkey().to_bytes(),
|
|
to_chain: 1,
|
|
fee: U256::from(0),
|
|
};
|
|
|
|
let message = payload.try_to_vec().unwrap();
|
|
let (vaa, _, _) = common::generate_vaa(
|
|
[0u8; 32],
|
|
2,
|
|
message,
|
|
nonce,
|
|
0
|
|
);
|
|
common::post_vaa(client, bridge, payer, vaa.clone()).unwrap();
|
|
|
|
let mut msg_derivation_data = &PostedVAADerivationData {
|
|
payload_hash: bridge::instructions::hash_vaa(&vaa).to_vec(),
|
|
};
|
|
let message_key =
|
|
PostedVAA::<'_, { AccountState::MaybeInitialized }>::key(&msg_derivation_data, &bridge);
|
|
|
|
assert!(common::complete_transfer_wrapped(
|
|
client,
|
|
token_bridge,
|
|
bridge,
|
|
&message_key,
|
|
vaa,
|
|
payload,
|
|
payer,
|
|
).is_err());
|
|
}
|