Allow Sollet asset migration

Change-Id: Id3fde0ef232fa2e8ed1435be34fe2b885ecd2ef7
This commit is contained in:
Jordan Sexton 2021-09-06 19:50:38 -05:00 committed by Hendrik Hofstadt
parent 94695ee125
commit 59e0e586ef
10 changed files with 453 additions and 45 deletions

View File

@ -1942,6 +1942,50 @@ dependencies = [
"ucd-trie",
]
[[package]]
name = "phf"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ac8b67553a7ca9457ce0e526948cad581819238f4a9d1ea74545851fa24f37"
dependencies = [
"phf_macros",
"phf_shared",
"proc-macro-hack",
]
[[package]]
name = "phf_generator"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d43f3220d96e0080cc9ea234978ccd80d904eafb17be31bb0f76daaea6493082"
dependencies = [
"phf_shared",
"rand 0.8.4",
]
[[package]]
name = "phf_macros"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b706f5936eb50ed880ae3009395b43ed19db5bff2ebd459c95e7bf013a89ab86"
dependencies = [
"phf_generator",
"phf_shared",
"proc-macro-hack",
"proc-macro2 1.0.28",
"quote 1.0.9",
"syn 1.0.75",
]
[[package]]
name = "phf_shared"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a68318426de33640f02be62b4ae8eb1261be2efbc337b60c54d845bf4484e0d9"
dependencies = [
"siphasher",
]
[[package]]
name = "pin-project-lite"
version = "0.2.7"
@ -2556,6 +2600,12 @@ version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335"
[[package]]
name = "siphasher"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b"
[[package]]
name = "slab"
version = "0.4.4"
@ -3390,6 +3440,7 @@ dependencies = [
"hex",
"hex-literal",
"libsecp256k1",
"phf",
"primitive-types",
"rand 0.7.3",
"rocksalt",

View File

@ -14,6 +14,7 @@ trace = ["solitaire/trace"]
wasm = ["no-entrypoint"]
client = ["solitaire-client", "solitaire/client", "no-entrypoint"]
cpi = ["no-entrypoint"]
test = []
default = []
[dependencies]
@ -31,6 +32,8 @@ spl-token-metadata = { path = "../token-metadata" }
wasm-bindgen = { version = "0.2.74", features = ["serde-serialize"] }
serde = { version = "1.0", features = ["derive"] }
rand = { version = "0.7.3", optional = true }
hex = "0.4.3"
phf = { version = "0.9", default-features = false, features=["macros"] }
[dev-dependencies]
hex = "*"

View File

@ -12,6 +12,7 @@ use crate::{
WrappedMint,
WrappedTokenMeta,
},
api::derive_mint_for_token,
messages::PayloadTransfer,
types::*,
TokenBridgeError::*,
@ -241,6 +242,27 @@ pub fn complete_wrapped(
accs.vaa.verify(ctx.program_id)?;
accs.vaa.claim(ctx, accs.payer.key)?;
let (_, is_sollet) =
derive_mint_for_token(ctx.program_id, accs.vaa.token_address, accs.vaa.token_chain);
let (amount, fee) = if is_sollet && accs.wrapped_meta.original_decimals > 6 {
// Sollet assets are truncated to 6 decimals, however Wormhole uses 8 and assumes
// wire-truncation to 8 decimals.
(
accs.vaa
.amount
.as_u64()
.checked_div(10u64.pow(2.min(accs.wrapped_meta.original_decimals as u32 - 6)))
.unwrap(),
accs.vaa
.fee
.as_u64()
.checked_div(10u64.pow(2.min(accs.wrapped_meta.original_decimals as u32 - 6)))
.unwrap(),
)
} else {
(accs.vaa.amount.as_u64(), accs.vaa.fee.as_u64())
};
// Mint tokens
let mint_ix = spl_token::instruction::mint_to(
&spl_token::id(),
@ -248,11 +270,7 @@ pub fn complete_wrapped(
accs.to.info().key,
accs.mint_authority.key,
&[],
accs.vaa
.amount
.as_u64()
.checked_sub(accs.vaa.fee.as_u64())
.unwrap(),
amount.checked_sub(fee).unwrap(),
)?;
invoke_seeded(&mint_ix, ctx, &accs.mint_authority, None)?;

View File

@ -13,8 +13,13 @@ use crate::{
},
messages::PayloadAssetMeta,
types::*,
TokenBridgeError::InvalidMint,
};
use bridge::vaa::ClaimableVAA;
use bridge::{
api::ForeignAddress,
vaa::ClaimableVAA,
};
use phf::phf_map;
use solana_program::{
account_info::AccountInfo,
program::invoke_signed,
@ -38,10 +43,12 @@ use spl_token::{
};
use std::{
cmp::min,
convert::TryInto,
ops::{
Deref,
DerefMut,
},
str::FromStr,
};
#[derive(FromAccounts)]
@ -53,7 +60,7 @@ pub struct CreateWrapped<'b> {
pub vaa: ClaimableVAA<'b, PayloadAssetMeta>,
// New Wrapped
pub mint: Mut<WrappedMint<'b, { AccountState::Uninitialized }>>,
pub mint: Mut<WrappedMint<'b, { AccountState::MaybeInitialized }>>,
pub meta: Mut<WrappedTokenMeta<'b, { AccountState::Uninitialized }>>,
/// SPL Metadata for the associated Mint
@ -94,14 +101,94 @@ impl<'b> InstructionContext<'b> for CreateWrapped<'b> {
#[derive(BorshDeserialize, BorshSerialize, Default)]
pub struct CreateWrappedData {}
#[cfg(not(feature = "test"))]
pub static SOLLET_MINTS: phf::Map<&str, (u16, &str)> = phf_map! {
// "WETH",
"000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" => (2, "2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk"),
// "YFI",
"0000000000000000000000000bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e" => (2, "3JSf5tPeuscJGtaCp5giEiDhv51gQ4v3zWg8DGgyLfAB"),
// "LINK",
"000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca" => (2, "CWE8jPTUYhdCTZYWPTe1o5DFqfdjzWKc9WKz6rSjQUdG"),
// "SUSHI",
"0000000000000000000000006b3595068778dd592e39a122f4f5a5cf09c90fe2" => (2, "AR1Mtgh7zAtxuxGd2XPovXPVjcSdY3i4rQYisNadjfKy"),
// "ALEPH",
"00000000000000000000000027702a26126e0B3702af63Ee09aC4d1A084EF628" => (2, "CsZ5LZkDS7h9TDKjrbL7VAwQZ9nsRu8vJLhRYfmGaN8K"),
// "SXP",
"0000000000000000000000008ce9137d39326ad0cd6491fb5cc0cba0e089b6a9" => (2, "SF3oTvfWzEP3DTwGSvUXRrGTvr75pdZNnBLAH9bzMuX"),
// "CREAM",
"0000000000000000000000002ba592F78dB6436527729929AAf6c908497cB200" => (2, "5Fu5UUgbjpUvdBveb3a1JTNirL8rXtiYeSMWvKjtUNQv"),
// "FRONT",
"000000000000000000000000f8C3527CC04340b208C854E985240c02F7B7793f" => (2, "9S4t2NEAiJVMvPdRYKVrfJpBafPBLtvbvyS3DecojQHw"),
// "AKRO",
"0000000000000000000000008ab7404063ec4dbcfd4598215992dc3f8ec853d7" => (2, "6WNVCuxCGJzNjmMZoKyhZJwvJ5tYpsLyAtagzYASqBoF"),
// "HXRO",
"0000000000000000000000004bd70556ae3f8a6ec6c4080a0c327b24325438f3" => (2, "DJafV9qemGp7mLMEn5wrfqaFwxsbLgUsGVS16zKRk9kc"),
// "UNI",
"0000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984" => (2, "DEhAasscXF4kEGxFgJ3bq4PpVGp5wyUxMRvn6TzGVHaw"),
// "FTT",
"00000000000000000000000050d1c9771902476076ecfc8b2a83ad6b9355a4c9" => (2, "AGFEad2et2ZJif9jaGpdMixQqvW5i81aBdvKe7PHNfz3"),
// "LUA",
"000000000000000000000000b1f66997a5760428d3a87d68b90bfe0ae64121cc" => (2, "EqWCKXfs3x47uVosDpTRgFniThL9Y8iCztJaapxbEaVX"),
// "MATH",
"00000000000000000000000008d967bb0134f2d07f7cfb6e246680c53927dd30" => (2, "GeDS162t9yGJuLEHPWXXGrb1zwkzinCgRwnT8vHYjKza"),
// "KEEP",
"00000000000000000000000085eee30c52b0b379b046fb0f85f4f3dc3009afec" => (2, "GUohe4DJUA5FKPWo3joiPgsB7yzer7LpDmt1Vhzy3Zht"),
// "SWAG",
"00000000000000000000000087eDfFDe3E14c7a66c9b9724747a1C5696b742e6" => (2, "9F9fNTT6qwjsu4X4yWYKZpsbw5qT7o6yR2i57JF2jagy"),
// "CEL",
"000000000000000000000000aaaebe6fe48e54f431b0c390cfaf0b017d09d42d" => (2, "DgHK9mfhMtUwwv54GChRrU54T2Em5cuszq2uMuen1ZVE"),
// "RSR",
"0000000000000000000000008762db106b2c2a0bccb3a80d1ed41273552616e8" => (2, "7ncCLJpP3MNww17LW8bRvx8odQQnubNtfNZBL5BgAEHW"),
// "1INCH",
"000000000000000000000000111111111117dc0aa78b770fa6a738034120c302" => (2, "5wihEYGca7X4gSe97C5mVcqNsfxBzhdTwpv72HKs25US"),
// "GRT",
"000000000000000000000000c944e90c64b2c07662a292be6244bdf05cda44a7" => (2, "38i2NQxjp5rt5B3KogqrxmBxgrAwaB3W1f1GmiKqh9MS"),
// "COMP",
"000000000000000000000000c00e94cb662c3520282e6f5717214004a7f26888" => (2, "Avz2fmevhhu87WYtWQCFj9UjKRjF9Z9QWwN2ih9yF95G"),
// "PAXG",
"00000000000000000000000045804880De22913dAFE09f4980848ECE6EcbAf78" => (2, "9wRD14AhdZ3qV8et3eBQVsrb3UoBZDUbJGyFckpTg8sj"),
};
#[cfg(feature = "test")]
pub static SOLLET_MINTS: phf::Map<&str, (u16, &str)> = phf_map! {
// "TEST",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" => (2, "FDhdMYh3KsF64Jxzh8tnx9rJXQTcN461rguUK9z9zm64"),
};
pub fn derive_mint_for_token(
program_id: &Pubkey,
token_address: Address,
token_chain: ChainID,
) -> (Pubkey, bool) {
let mut sollet_mint = SOLLET_MINTS.get(hex::encode(token_address).as_str());
if let Some(mint) = sollet_mint {
if mint.0 == token_chain {
return (Pubkey::from_str(mint.1).unwrap(), true);
}
}
(
WrappedMint::<'_, { AccountState::Uninitialized }>::key(
&WrappedDerivationData {
token_chain,
token_address,
},
&program_id,
),
false,
)
}
pub fn create_wrapped(
ctx: &ExecutionContext,
accs: &mut CreateWrapped,
data: CreateWrappedData,
) -> Result<()> {
let derivation_data: WrappedDerivationData = (&*accs).into();
accs.mint
.verify_derivation(ctx.program_id, &derivation_data)?;
let (mint, is_sollet) =
derive_mint_for_token(ctx.program_id, accs.vaa.token_address, accs.vaa.token_chain);
if *accs.mint.info().key != mint {
return Err(InvalidMint.into());
}
let meta_derivation_data: WrappedMetaDerivationData = (&*accs).into();
accs.meta
@ -114,19 +201,21 @@ pub fn create_wrapped(
accs.vaa.verify(ctx.program_id)?;
accs.vaa.claim(ctx, accs.payer.key)?;
// Create mint account
accs.mint
.create(&((&*accs).into()), ctx, accs.payer.key, Exempt)?;
if !is_sollet {
// Create mint account
accs.mint
.create(&((&*accs).into()), ctx, accs.payer.key, Exempt)?;
// Initialize mint
let init_ix = spl_token::instruction::initialize_mint(
&spl_token::id(),
accs.mint.info().key,
accs.mint_authority.key,
None,
min(8, accs.vaa.decimals), // Limit to 8 decimals, truncation is handled on the other side
)?;
invoke_signed(&init_ix, ctx.accounts, &[])?;
// Initialize mint
let init_ix = spl_token::instruction::initialize_mint(
&spl_token::id(),
accs.mint.info().key,
accs.mint_authority.key,
None,
min(8, accs.vaa.decimals), // Limit to 8 decimals, truncation is handled on the other side
)?;
invoke_signed(&init_ix, ctx.accounts, &[])?;
}
// Create meta account
accs.meta
@ -166,6 +255,7 @@ pub fn create_wrapped(
// Populate meta account
accs.meta.chain = accs.vaa.token_chain;
accs.meta.token_address = accs.vaa.token_address;
accs.meta.original_decimals = accs.vaa.decimals;
Ok(())
}

View File

@ -0,0 +1,112 @@
[
{
"address": "2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk",
"symbol": "ETH",
"ethAddress": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
},
{
"address": "3JSf5tPeuscJGtaCp5giEiDhv51gQ4v3zWg8DGgyLfAB",
"symbol": "YFI",
"ethAddress": "0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e"
},
{
"address": "CWE8jPTUYhdCTZYWPTe1o5DFqfdjzWKc9WKz6rSjQUdG",
"symbol": "LINK",
"ethAddress": "0x514910771af9ca656af840dff83e8264ecf986ca"
},
{
"address": "AR1Mtgh7zAtxuxGd2XPovXPVjcSdY3i4rQYisNadjfKy",
"symbol": "SUSHI",
"ethAddress": "0x6b3595068778dd592e39a122f4f5a5cf09c90fe2"
},
{
"address": "CsZ5LZkDS7h9TDKjrbL7VAwQZ9nsRu8vJLhRYfmGaN8K",
"symbol": "ALEPH",
"ethAddress": "0x27702a26126e0B3702af63Ee09aC4d1A084EF628"
},
{
"address": "SF3oTvfWzEP3DTwGSvUXRrGTvr75pdZNnBLAH9bzMuX",
"symbol": "SXP",
"ethAddress": "0x8ce9137d39326ad0cd6491fb5cc0cba0e089b6a9"
},
{
"address": "5Fu5UUgbjpUvdBveb3a1JTNirL8rXtiYeSMWvKjtUNQv",
"symbol": "CREAM",
"ethAddress": "0x2ba592F78dB6436527729929AAf6c908497cB200"
},
{
"address": "9S4t2NEAiJVMvPdRYKVrfJpBafPBLtvbvyS3DecojQHw",
"symbol": "FRONT",
"ethAddress": "0xf8C3527CC04340b208C854E985240c02F7B7793f"
},
{
"address": "6WNVCuxCGJzNjmMZoKyhZJwvJ5tYpsLyAtagzYASqBoF",
"symbol": "AKRO",
"ethAddress": "0x8ab7404063ec4dbcfd4598215992dc3f8ec853d7"
},
{
"address": "DJafV9qemGp7mLMEn5wrfqaFwxsbLgUsGVS16zKRk9kc",
"symbol": "HXRO",
"ethAddress": "0x4bd70556ae3f8a6ec6c4080a0c327b24325438f3"
},
{
"address": "DEhAasscXF4kEGxFgJ3bq4PpVGp5wyUxMRvn6TzGVHaw",
"symbol": "UNI",
"ethAddress": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"
},
{
"address": "AGFEad2et2ZJif9jaGpdMixQqvW5i81aBdvKe7PHNfz3",
"symbol": "FTT",
"ethAddress": "0x50d1c9771902476076ecfc8b2a83ad6b9355a4c9"
},
{
"address": "EqWCKXfs3x47uVosDpTRgFniThL9Y8iCztJaapxbEaVX",
"symbol": "LUA",
"ethAddress": "0xb1f66997a5760428d3a87d68b90bfe0ae64121cc"
},
{
"address": "GeDS162t9yGJuLEHPWXXGrb1zwkzinCgRwnT8vHYjKza",
"symbol": "MATH",
"ethAddress": "0x08d967bb0134f2d07f7cfb6e246680c53927dd30"
},
{
"address": "GUohe4DJUA5FKPWo3joiPgsB7yzer7LpDmt1Vhzy3Zht",
"symbol": "KEEP",
"ethAddress": "0x85eee30c52b0b379b046fb0f85f4f3dc3009afec"
},
{
"address": "9F9fNTT6qwjsu4X4yWYKZpsbw5qT7o6yR2i57JF2jagy",
"symbol": "SWAG",
"ethAddress": "0x87eDfFDe3E14c7a66c9b9724747a1C5696b742e6"
},
{
"address": "DgHK9mfhMtUwwv54GChRrU54T2Em5cuszq2uMuen1ZVE",
"symbol": "CEL",
"ethAddress": "0xaaaebe6fe48e54f431b0c390cfaf0b017d09d42d"
},
{
"address": "7ncCLJpP3MNww17LW8bRvx8odQQnubNtfNZBL5BgAEHW",
"symbol": "RSR",
"ethAddress": "0x8762db106b2c2a0bccb3a80d1ed41273552616e8"
},
{
"address": "5wihEYGca7X4gSe97C5mVcqNsfxBzhdTwpv72HKs25US",
"symbol": "1INCH",
"ethAddress": "0x111111111117dc0aa78b770fa6a738034120c302"
},
{
"address": "38i2NQxjp5rt5B3KogqrxmBxgrAwaB3W1f1GmiKqh9MS",
"symbol": "GRT",
"ethAddress": "0xc944e90c64b2c07662a292be6244bdf05cda44a7"
},
{
"address": "Avz2fmevhhu87WYtWQCFj9UjKRjF9Z9QWwN2ih9yF95G",
"symbol": "COMP",
"ethAddress": "0xc00e94cb662c3520282e6f5717214004a7f26888"
},
{
"address": "9wRD14AhdZ3qV8et3eBQVsrb3UoBZDUbJGyFckpTg8sj",
"symbol": "PAXG",
"ethAddress": "0x45804880De22913dAFE09f4980848ECE6EcbAf78"
}
]

View File

@ -0,0 +1,44 @@
// "WETH",
(2, b"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2") => b"2FPyTwcZLUg1MDrwsyoP4D6s1tM7hAkHYRjkNb5w6Pxk",
// "YFI",
(2, b"0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e") => b"3JSf5tPeuscJGtaCp5giEiDhv51gQ4v3zWg8DGgyLfAB",
// "LINK",
(2, b"0x514910771af9ca656af840dff83e8264ecf986ca") => b"CWE8jPTUYhdCTZYWPTe1o5DFqfdjzWKc9WKz6rSjQUdG",
// "SUSHI",
(2, b"0x6b3595068778dd592e39a122f4f5a5cf09c90fe2") => b"AR1Mtgh7zAtxuxGd2XPovXPVjcSdY3i4rQYisNadjfKy",
// "ALEPH",
(2, b"0x27702a26126e0B3702af63Ee09aC4d1A084EF628") => b"CsZ5LZkDS7h9TDKjrbL7VAwQZ9nsRu8vJLhRYfmGaN8K",
// "SXP",
(2, b"0x8ce9137d39326ad0cd6491fb5cc0cba0e089b6a9") => b"SF3oTvfWzEP3DTwGSvUXRrGTvr75pdZNnBLAH9bzMuX",
// "CREAM",
(2, b"0x2ba592F78dB6436527729929AAf6c908497cB200") => b"5Fu5UUgbjpUvdBveb3a1JTNirL8rXtiYeSMWvKjtUNQv",
// "FRONT",
(2, b"0xf8C3527CC04340b208C854E985240c02F7B7793f") => b"9S4t2NEAiJVMvPdRYKVrfJpBafPBLtvbvyS3DecojQHw",
// "AKRO",
(2, b"0x8ab7404063ec4dbcfd4598215992dc3f8ec853d7") => b"6WNVCuxCGJzNjmMZoKyhZJwvJ5tYpsLyAtagzYASqBoF",
// "HXRO",
(2, b"0x4bd70556ae3f8a6ec6c4080a0c327b24325438f3") => b"DJafV9qemGp7mLMEn5wrfqaFwxsbLgUsGVS16zKRk9kc",
// "UNI",
(2, b"0x1f9840a85d5af5bf1d1762f925bdaddc4201f984") => b"DEhAasscXF4kEGxFgJ3bq4PpVGp5wyUxMRvn6TzGVHaw",
// "FTT",
(2, b"0x50d1c9771902476076ecfc8b2a83ad6b9355a4c9") => b"AGFEad2et2ZJif9jaGpdMixQqvW5i81aBdvKe7PHNfz3",
// "LUA",
(2, b"0xb1f66997a5760428d3a87d68b90bfe0ae64121cc") => b"EqWCKXfs3x47uVosDpTRgFniThL9Y8iCztJaapxbEaVX",
// "MATH",
(2, b"0x08d967bb0134f2d07f7cfb6e246680c53927dd30") => b"GeDS162t9yGJuLEHPWXXGrb1zwkzinCgRwnT8vHYjKza",
// "KEEP",
(2, b"0x85eee30c52b0b379b046fb0f85f4f3dc3009afec") => b"GUohe4DJUA5FKPWo3joiPgsB7yzer7LpDmt1Vhzy3Zht",
// "SWAG",
(2, b"0x87eDfFDe3E14c7a66c9b9724747a1C5696b742e6") => b"9F9fNTT6qwjsu4X4yWYKZpsbw5qT7o6yR2i57JF2jagy",
// "CEL",
(2, b"0xaaaebe6fe48e54f431b0c390cfaf0b017d09d42d") => b"DgHK9mfhMtUwwv54GChRrU54T2Em5cuszq2uMuen1ZVE",
// "RSR",
(2, b"0x8762db106b2c2a0bccb3a80d1ed41273552616e8") => b"7ncCLJpP3MNww17LW8bRvx8odQQnubNtfNZBL5BgAEHW",
// "1INCH",
(2, b"0x111111111117dc0aa78b770fa6a738034120c302") => b"5wihEYGca7X4gSe97C5mVcqNsfxBzhdTwpv72HKs25US",
// "GRT",
(2, b"0xc944e90c64b2c07662a292be6244bdf05cda44a7") => b"38i2NQxjp5rt5B3KogqrxmBxgrAwaB3W1f1GmiKqh9MS",
// "COMP",
(2, b"0xc00e94cb662c3520282e6f5717214004a7f26888") => b"Avz2fmevhhu87WYtWQCFj9UjKRjF9Z9QWwN2ih9yF95G",
// "PAXG",
(2, b"0x45804880De22913dAFE09f4980848ECE6EcbAf78") => b"9wRD14AhdZ3qV8et3eBQVsrb3UoBZDUbJGyFckpTg8sj",

View File

@ -13,6 +13,7 @@ use crate::{
WrappedMint,
WrappedTokenMeta,
},
api::derive_mint_for_token,
messages::PayloadTransfer,
types::*,
TokenBridgeError,
@ -330,14 +331,34 @@ pub fn transfer_wrapped(
invoke(&transfer_ix, ctx.accounts)?;
let (_, is_sollet) = derive_mint_for_token(
ctx.program_id,
accs.wrapped_meta.token_address,
accs.wrapped_meta.chain,
);
let (amount, fee) = if is_sollet && accs.wrapped_meta.original_decimals > 6 {
// Sollet assets are truncated to 6 decimals, however Wormhole uses 8 and assumes
// wire-truncation to 8 decimals.
(
data.amount
.checked_mul(10u64.pow(2.min(accs.wrapped_meta.original_decimals as u32 - 6)))
.unwrap(),
data.fee
.checked_mul(10u64.pow(2.min(accs.wrapped_meta.original_decimals as u32 - 6)))
.unwrap(),
)
} else {
(data.amount, data.fee)
};
// Post message
let payload = PayloadTransfer {
amount: U256::from(data.amount),
amount: U256::from(amount),
token_address: accs.wrapped_meta.token_address,
token_chain: accs.wrapped_meta.chain,
to: data.target_address,
to_chain: data.target_chain,
fee: U256::from(data.fee),
fee: U256::from(fee),
};
let params = (
bridge::instruction::Instruction::PostMessage,

View File

@ -21,12 +21,14 @@ use crate::{
CompleteNativeData,
CompleteWrappedData,
},
derive_mint_for_token,
AttestTokenData,
CreateWrappedData,
RegisterChainData,
TransferNativeData,
TransferWrappedData,
UpgradeContractData,
SOLLET_MINTS,
},
messages::{
PayloadAssetMeta,
@ -169,13 +171,8 @@ pub fn complete_wrapped(
},
&program_id,
);
let mint_key = WrappedMint::<'_, { AccountState::Uninitialized }>::key(
&WrappedDerivationData {
token_chain: payload.token_chain,
token_address: payload.token_address,
},
&program_id,
);
let mint_key = derive_mint_for_token(&program_id, payload.token_address, payload.token_chain).0;
let meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
&WrappedMetaDerivationData { mint_key },
&program_id,
@ -228,13 +225,7 @@ pub fn create_wrapped(
},
&program_id,
);
let mint_key = WrappedMint::<'_, { AccountState::Uninitialized }>::key(
&WrappedDerivationData {
token_chain: payload.token_chain,
token_address: payload.token_address,
},
&program_id,
);
let mint_key = derive_mint_for_token(&program_id, payload.token_address, payload.token_chain).0;
let mint_meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
&WrappedMetaDerivationData { mint_key },
&program_id,
@ -404,13 +395,7 @@ pub fn transfer_wrapped(
) -> solitaire::Result<Instruction> {
let config_key = ConfigAccount::<'_, { AccountState::Uninitialized }>::key(None, &program_id);
let wrapped_mint_key = WrappedMint::<'_, { AccountState::Uninitialized }>::key(
&WrappedDerivationData {
token_chain,
token_address,
},
&program_id,
);
let wrapped_mint_key = derive_mint_for_token(&program_id, token_address, token_chain).0;
let wrapped_meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
&WrappedMetaDerivationData {
mint_key: wrapped_mint_key,

View File

@ -50,6 +50,7 @@ impl Owned for EndpointRegistration {
pub struct WrappedMeta {
pub chain: ChainID,
pub token_address: Address,
pub original_decimals: u8,
}
impl Owned for WrappedMeta {

View File

@ -94,9 +94,11 @@ use std::{
use token_bridge::{
accounts::{
EmitterAccount,
MintSigner,
WrappedDerivationData,
WrappedMint,
},
api::SOLLET_MINTS,
messages::{
PayloadAssetMeta,
PayloadGovernanceRegisterChain,
@ -271,6 +273,9 @@ fn run_integration_tests() {
.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);
}
fn test_attest(context: &mut Context) -> () {
@ -607,6 +612,84 @@ fn test_create_wrapped(context: &mut Context) -> (Pubkey) {
);
}
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!("{:?}", SOLLET_MINTS);
println!("{:?}", SOLLET_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::{