Allow Sollet asset migration
Change-Id: Id3fde0ef232fa2e8ed1435be34fe2b885ecd2ef7
This commit is contained in:
parent
94695ee125
commit
59e0e586ef
|
@ -1942,6 +1942,50 @@ dependencies = [
|
||||||
"ucd-trie",
|
"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]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
|
@ -2556,6 +2600,12 @@ version = "1.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335"
|
checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "siphasher"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.4"
|
version = "0.4.4"
|
||||||
|
@ -3390,6 +3440,7 @@ dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"hex-literal",
|
"hex-literal",
|
||||||
"libsecp256k1",
|
"libsecp256k1",
|
||||||
|
"phf",
|
||||||
"primitive-types",
|
"primitive-types",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"rocksalt",
|
"rocksalt",
|
||||||
|
|
|
@ -14,6 +14,7 @@ trace = ["solitaire/trace"]
|
||||||
wasm = ["no-entrypoint"]
|
wasm = ["no-entrypoint"]
|
||||||
client = ["solitaire-client", "solitaire/client", "no-entrypoint"]
|
client = ["solitaire-client", "solitaire/client", "no-entrypoint"]
|
||||||
cpi = ["no-entrypoint"]
|
cpi = ["no-entrypoint"]
|
||||||
|
test = []
|
||||||
default = []
|
default = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
@ -31,6 +32,8 @@ spl-token-metadata = { path = "../token-metadata" }
|
||||||
wasm-bindgen = { version = "0.2.74", features = ["serde-serialize"] }
|
wasm-bindgen = { version = "0.2.74", features = ["serde-serialize"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
rand = { version = "0.7.3", optional = true }
|
rand = { version = "0.7.3", optional = true }
|
||||||
|
hex = "0.4.3"
|
||||||
|
phf = { version = "0.9", default-features = false, features=["macros"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex = "*"
|
hex = "*"
|
||||||
|
|
|
@ -12,6 +12,7 @@ use crate::{
|
||||||
WrappedMint,
|
WrappedMint,
|
||||||
WrappedTokenMeta,
|
WrappedTokenMeta,
|
||||||
},
|
},
|
||||||
|
api::derive_mint_for_token,
|
||||||
messages::PayloadTransfer,
|
messages::PayloadTransfer,
|
||||||
types::*,
|
types::*,
|
||||||
TokenBridgeError::*,
|
TokenBridgeError::*,
|
||||||
|
@ -241,6 +242,27 @@ pub fn complete_wrapped(
|
||||||
accs.vaa.verify(ctx.program_id)?;
|
accs.vaa.verify(ctx.program_id)?;
|
||||||
accs.vaa.claim(ctx, accs.payer.key)?;
|
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
|
// Mint tokens
|
||||||
let mint_ix = spl_token::instruction::mint_to(
|
let mint_ix = spl_token::instruction::mint_to(
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
|
@ -248,11 +270,7 @@ pub fn complete_wrapped(
|
||||||
accs.to.info().key,
|
accs.to.info().key,
|
||||||
accs.mint_authority.key,
|
accs.mint_authority.key,
|
||||||
&[],
|
&[],
|
||||||
accs.vaa
|
amount.checked_sub(fee).unwrap(),
|
||||||
.amount
|
|
||||||
.as_u64()
|
|
||||||
.checked_sub(accs.vaa.fee.as_u64())
|
|
||||||
.unwrap(),
|
|
||||||
)?;
|
)?;
|
||||||
invoke_seeded(&mint_ix, ctx, &accs.mint_authority, None)?;
|
invoke_seeded(&mint_ix, ctx, &accs.mint_authority, None)?;
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,13 @@ use crate::{
|
||||||
},
|
},
|
||||||
messages::PayloadAssetMeta,
|
messages::PayloadAssetMeta,
|
||||||
types::*,
|
types::*,
|
||||||
|
TokenBridgeError::InvalidMint,
|
||||||
};
|
};
|
||||||
use bridge::vaa::ClaimableVAA;
|
use bridge::{
|
||||||
|
api::ForeignAddress,
|
||||||
|
vaa::ClaimableVAA,
|
||||||
|
};
|
||||||
|
use phf::phf_map;
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo,
|
account_info::AccountInfo,
|
||||||
program::invoke_signed,
|
program::invoke_signed,
|
||||||
|
@ -38,10 +43,12 @@ use spl_token::{
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
cmp::min,
|
cmp::min,
|
||||||
|
convert::TryInto,
|
||||||
ops::{
|
ops::{
|
||||||
Deref,
|
Deref,
|
||||||
DerefMut,
|
DerefMut,
|
||||||
},
|
},
|
||||||
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(FromAccounts)]
|
#[derive(FromAccounts)]
|
||||||
|
@ -53,7 +60,7 @@ pub struct CreateWrapped<'b> {
|
||||||
pub vaa: ClaimableVAA<'b, PayloadAssetMeta>,
|
pub vaa: ClaimableVAA<'b, PayloadAssetMeta>,
|
||||||
|
|
||||||
// New Wrapped
|
// New Wrapped
|
||||||
pub mint: Mut<WrappedMint<'b, { AccountState::Uninitialized }>>,
|
pub mint: Mut<WrappedMint<'b, { AccountState::MaybeInitialized }>>,
|
||||||
pub meta: Mut<WrappedTokenMeta<'b, { AccountState::Uninitialized }>>,
|
pub meta: Mut<WrappedTokenMeta<'b, { AccountState::Uninitialized }>>,
|
||||||
|
|
||||||
/// SPL Metadata for the associated Mint
|
/// SPL Metadata for the associated Mint
|
||||||
|
@ -94,14 +101,94 @@ impl<'b> InstructionContext<'b> for CreateWrapped<'b> {
|
||||||
#[derive(BorshDeserialize, BorshSerialize, Default)]
|
#[derive(BorshDeserialize, BorshSerialize, Default)]
|
||||||
pub struct CreateWrappedData {}
|
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(
|
pub fn create_wrapped(
|
||||||
ctx: &ExecutionContext,
|
ctx: &ExecutionContext,
|
||||||
accs: &mut CreateWrapped,
|
accs: &mut CreateWrapped,
|
||||||
data: CreateWrappedData,
|
data: CreateWrappedData,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let derivation_data: WrappedDerivationData = (&*accs).into();
|
let (mint, is_sollet) =
|
||||||
accs.mint
|
derive_mint_for_token(ctx.program_id, accs.vaa.token_address, accs.vaa.token_chain);
|
||||||
.verify_derivation(ctx.program_id, &derivation_data)?;
|
if *accs.mint.info().key != mint {
|
||||||
|
return Err(InvalidMint.into());
|
||||||
|
}
|
||||||
|
|
||||||
let meta_derivation_data: WrappedMetaDerivationData = (&*accs).into();
|
let meta_derivation_data: WrappedMetaDerivationData = (&*accs).into();
|
||||||
accs.meta
|
accs.meta
|
||||||
|
@ -114,19 +201,21 @@ pub fn create_wrapped(
|
||||||
accs.vaa.verify(ctx.program_id)?;
|
accs.vaa.verify(ctx.program_id)?;
|
||||||
accs.vaa.claim(ctx, accs.payer.key)?;
|
accs.vaa.claim(ctx, accs.payer.key)?;
|
||||||
|
|
||||||
// Create mint account
|
if !is_sollet {
|
||||||
accs.mint
|
// Create mint account
|
||||||
.create(&((&*accs).into()), ctx, accs.payer.key, Exempt)?;
|
accs.mint
|
||||||
|
.create(&((&*accs).into()), ctx, accs.payer.key, Exempt)?;
|
||||||
|
|
||||||
// Initialize mint
|
// Initialize mint
|
||||||
let init_ix = spl_token::instruction::initialize_mint(
|
let init_ix = spl_token::instruction::initialize_mint(
|
||||||
&spl_token::id(),
|
&spl_token::id(),
|
||||||
accs.mint.info().key,
|
accs.mint.info().key,
|
||||||
accs.mint_authority.key,
|
accs.mint_authority.key,
|
||||||
None,
|
None,
|
||||||
min(8, accs.vaa.decimals), // Limit to 8 decimals, truncation is handled on the other side
|
min(8, accs.vaa.decimals), // Limit to 8 decimals, truncation is handled on the other side
|
||||||
)?;
|
)?;
|
||||||
invoke_signed(&init_ix, ctx.accounts, &[])?;
|
invoke_signed(&init_ix, ctx.accounts, &[])?;
|
||||||
|
}
|
||||||
|
|
||||||
// Create meta account
|
// Create meta account
|
||||||
accs.meta
|
accs.meta
|
||||||
|
@ -166,6 +255,7 @@ pub fn create_wrapped(
|
||||||
// Populate meta account
|
// Populate meta account
|
||||||
accs.meta.chain = accs.vaa.token_chain;
|
accs.meta.chain = accs.vaa.token_chain;
|
||||||
accs.meta.token_address = accs.vaa.token_address;
|
accs.meta.token_address = accs.vaa.token_address;
|
||||||
|
accs.meta.original_decimals = accs.vaa.decimals;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
||||||
|
]
|
|
@ -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",
|
|
@ -13,6 +13,7 @@ use crate::{
|
||||||
WrappedMint,
|
WrappedMint,
|
||||||
WrappedTokenMeta,
|
WrappedTokenMeta,
|
||||||
},
|
},
|
||||||
|
api::derive_mint_for_token,
|
||||||
messages::PayloadTransfer,
|
messages::PayloadTransfer,
|
||||||
types::*,
|
types::*,
|
||||||
TokenBridgeError,
|
TokenBridgeError,
|
||||||
|
@ -330,14 +331,34 @@ pub fn transfer_wrapped(
|
||||||
|
|
||||||
invoke(&transfer_ix, ctx.accounts)?;
|
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
|
// Post message
|
||||||
let payload = PayloadTransfer {
|
let payload = PayloadTransfer {
|
||||||
amount: U256::from(data.amount),
|
amount: U256::from(amount),
|
||||||
token_address: accs.wrapped_meta.token_address,
|
token_address: accs.wrapped_meta.token_address,
|
||||||
token_chain: accs.wrapped_meta.chain,
|
token_chain: accs.wrapped_meta.chain,
|
||||||
to: data.target_address,
|
to: data.target_address,
|
||||||
to_chain: data.target_chain,
|
to_chain: data.target_chain,
|
||||||
fee: U256::from(data.fee),
|
fee: U256::from(fee),
|
||||||
};
|
};
|
||||||
let params = (
|
let params = (
|
||||||
bridge::instruction::Instruction::PostMessage,
|
bridge::instruction::Instruction::PostMessage,
|
||||||
|
|
|
@ -21,12 +21,14 @@ use crate::{
|
||||||
CompleteNativeData,
|
CompleteNativeData,
|
||||||
CompleteWrappedData,
|
CompleteWrappedData,
|
||||||
},
|
},
|
||||||
|
derive_mint_for_token,
|
||||||
AttestTokenData,
|
AttestTokenData,
|
||||||
CreateWrappedData,
|
CreateWrappedData,
|
||||||
RegisterChainData,
|
RegisterChainData,
|
||||||
TransferNativeData,
|
TransferNativeData,
|
||||||
TransferWrappedData,
|
TransferWrappedData,
|
||||||
UpgradeContractData,
|
UpgradeContractData,
|
||||||
|
SOLLET_MINTS,
|
||||||
},
|
},
|
||||||
messages::{
|
messages::{
|
||||||
PayloadAssetMeta,
|
PayloadAssetMeta,
|
||||||
|
@ -169,13 +171,8 @@ pub fn complete_wrapped(
|
||||||
},
|
},
|
||||||
&program_id,
|
&program_id,
|
||||||
);
|
);
|
||||||
let mint_key = WrappedMint::<'_, { AccountState::Uninitialized }>::key(
|
|
||||||
&WrappedDerivationData {
|
let mint_key = derive_mint_for_token(&program_id, payload.token_address, payload.token_chain).0;
|
||||||
token_chain: payload.token_chain,
|
|
||||||
token_address: payload.token_address,
|
|
||||||
},
|
|
||||||
&program_id,
|
|
||||||
);
|
|
||||||
let meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
|
let meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
|
||||||
&WrappedMetaDerivationData { mint_key },
|
&WrappedMetaDerivationData { mint_key },
|
||||||
&program_id,
|
&program_id,
|
||||||
|
@ -228,13 +225,7 @@ pub fn create_wrapped(
|
||||||
},
|
},
|
||||||
&program_id,
|
&program_id,
|
||||||
);
|
);
|
||||||
let mint_key = WrappedMint::<'_, { AccountState::Uninitialized }>::key(
|
let mint_key = derive_mint_for_token(&program_id, payload.token_address, payload.token_chain).0;
|
||||||
&WrappedDerivationData {
|
|
||||||
token_chain: payload.token_chain,
|
|
||||||
token_address: payload.token_address,
|
|
||||||
},
|
|
||||||
&program_id,
|
|
||||||
);
|
|
||||||
let mint_meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
|
let mint_meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
|
||||||
&WrappedMetaDerivationData { mint_key },
|
&WrappedMetaDerivationData { mint_key },
|
||||||
&program_id,
|
&program_id,
|
||||||
|
@ -404,13 +395,7 @@ pub fn transfer_wrapped(
|
||||||
) -> solitaire::Result<Instruction> {
|
) -> solitaire::Result<Instruction> {
|
||||||
let config_key = ConfigAccount::<'_, { AccountState::Uninitialized }>::key(None, &program_id);
|
let config_key = ConfigAccount::<'_, { AccountState::Uninitialized }>::key(None, &program_id);
|
||||||
|
|
||||||
let wrapped_mint_key = WrappedMint::<'_, { AccountState::Uninitialized }>::key(
|
let wrapped_mint_key = derive_mint_for_token(&program_id, token_address, token_chain).0;
|
||||||
&WrappedDerivationData {
|
|
||||||
token_chain,
|
|
||||||
token_address,
|
|
||||||
},
|
|
||||||
&program_id,
|
|
||||||
);
|
|
||||||
let wrapped_meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
|
let wrapped_meta_key = WrappedTokenMeta::<'_, { AccountState::Uninitialized }>::key(
|
||||||
&WrappedMetaDerivationData {
|
&WrappedMetaDerivationData {
|
||||||
mint_key: wrapped_mint_key,
|
mint_key: wrapped_mint_key,
|
||||||
|
|
|
@ -50,6 +50,7 @@ impl Owned for EndpointRegistration {
|
||||||
pub struct WrappedMeta {
|
pub struct WrappedMeta {
|
||||||
pub chain: ChainID,
|
pub chain: ChainID,
|
||||||
pub token_address: Address,
|
pub token_address: Address,
|
||||||
|
pub original_decimals: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Owned for WrappedMeta {
|
impl Owned for WrappedMeta {
|
||||||
|
|
|
@ -94,9 +94,11 @@ use std::{
|
||||||
use token_bridge::{
|
use token_bridge::{
|
||||||
accounts::{
|
accounts::{
|
||||||
EmitterAccount,
|
EmitterAccount,
|
||||||
|
MintSigner,
|
||||||
WrappedDerivationData,
|
WrappedDerivationData,
|
||||||
WrappedMint,
|
WrappedMint,
|
||||||
},
|
},
|
||||||
|
api::SOLLET_MINTS,
|
||||||
messages::{
|
messages::{
|
||||||
PayloadAssetMeta,
|
PayloadAssetMeta,
|
||||||
PayloadGovernanceRegisterChain,
|
PayloadGovernanceRegisterChain,
|
||||||
|
@ -271,6 +273,9 @@ fn run_integration_tests() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
test_transfer_wrapped_in(&mut context, wrapped_acc.pubkey());
|
test_transfer_wrapped_in(&mut context, wrapped_acc.pubkey());
|
||||||
test_transfer_wrapped(&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) -> () {
|
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) {
|
fn test_initialize(context: &mut Context) {
|
||||||
println!("Initialize");
|
println!("Initialize");
|
||||||
use token_bridge::{
|
use token_bridge::{
|
||||||
|
|
Loading…
Reference in New Issue