terra: Add fromAddress to payload 3

This commit is contained in:
Csongor Kiss 2022-09-26 14:38:18 -05:00 committed by Evan Gray
parent d0900c791a
commit 37ee5cf4a4
5 changed files with 239 additions and 128 deletions

View File

@ -33,6 +33,7 @@ use terra_cosmwasm::TerraQuerier;
use wormhole::{ use wormhole::{
byte_utils::{ byte_utils::{
extend_address_to_32, extend_address_to_32,
extend_address_to_32_array,
extend_string_to_32, extend_string_to_32,
get_string_from_32, get_string_from_32,
ByteUtils, ByteUtils,
@ -256,9 +257,12 @@ pub fn reply(deps: DepsMut, env: Env, _msg: Reply) -> StdResult<Response> {
Action::TRANSFER_WITH_PAYLOAD => { Action::TRANSFER_WITH_PAYLOAD => {
let info = TransferWithPayloadInfo::deserialize(&token_bridge_message.payload)?; let info = TransferWithPayloadInfo::deserialize(&token_bridge_message.payload)?;
Ok(( Ok((
info.transfer_info, info.as_transfer_info(),
TransferType::WithPayload { TransferType::WithPayload {
payload: info.payload, // put both the payload and sender_address into the payload
// field here (which we can do, since [`TransferType`] is
// parametric)
payload: (info.payload, info.sender_address),
}, },
)) ))
} }
@ -296,8 +300,13 @@ pub fn reply(deps: DepsMut, env: Env, _msg: Reply) -> StdResult<Response> {
TransferType::WithPayload { payload } => TokenBridgeMessage { TransferType::WithPayload { payload } => TokenBridgeMessage {
action: Action::TRANSFER_WITH_PAYLOAD, action: Action::TRANSFER_WITH_PAYLOAD,
payload: TransferWithPayloadInfo { payload: TransferWithPayloadInfo {
transfer_info, amount: transfer_info.amount,
payload, token_address: transfer_info.token_address,
token_chain: transfer_info.token_chain,
recipient: transfer_info.recipient,
recipient_chain: transfer_info.recipient_chain,
sender_address: payload.1,
payload: payload.0,
} }
.serialize(), .serialize(),
}, },
@ -843,7 +852,7 @@ fn handle_complete_transfer_token(
let transfer_info = match transfer_type { let transfer_info = match transfer_type {
TransferType::WithoutPayload => TransferInfo::deserialize(&data)?, TransferType::WithoutPayload => TransferInfo::deserialize(&data)?,
TransferType::WithPayload { payload: _ } => { TransferType::WithPayload { payload: _ } => {
TransferWithPayloadInfo::deserialize(&data)?.transfer_info TransferWithPayloadInfo::deserialize(&data)?.as_transfer_info()
} }
}; };
@ -988,7 +997,7 @@ fn handle_complete_transfer_token_native(
let transfer_info = match transfer_type { let transfer_info = match transfer_type {
TransferType::WithoutPayload => TransferInfo::deserialize(&data)?, TransferType::WithoutPayload => TransferInfo::deserialize(&data)?,
TransferType::WithPayload { payload: () } => { TransferType::WithPayload { payload: () } => {
TransferWithPayloadInfo::deserialize(&data)?.transfer_info TransferWithPayloadInfo::deserialize(&data)?.as_transfer_info()
} }
}; };
@ -1122,7 +1131,7 @@ fn handle_initiate_transfer_token(
} }
let asset_chain: u16; let asset_chain: u16;
let asset_address: Vec<u8>; let asset_address: [u8; 32];
let cfg: ConfigInfo = config_read(deps.storage).load()?; let cfg: ConfigInfo = config_read(deps.storage).load()?;
let asset_canonical: CanonicalAddr = deps.api.addr_canonicalize(&asset)?; let asset_canonical: CanonicalAddr = deps.api.addr_canonicalize(&asset)?;
@ -1130,6 +1139,10 @@ fn handle_initiate_transfer_token(
let mut messages: Vec<CosmosMsg> = vec![]; let mut messages: Vec<CosmosMsg> = vec![];
let mut submessages: Vec<SubMsg> = vec![]; let mut submessages: Vec<SubMsg> = vec![];
// we'll only need this for payload 3 transfers
let sender_address = deps.api.addr_canonicalize(&info.sender.to_string())?;
let sender_address = extend_address_to_32_array(&sender_address);
match wrapped_asset_address_read(deps.storage).load(asset_canonical.as_slice()) { match wrapped_asset_address_read(deps.storage).load(asset_canonical.as_slice()) {
Ok(_) => { Ok(_) => {
// If the fee is too large the user will receive nothing. // If the fee is too large the user will receive nothing.
@ -1153,30 +1166,38 @@ fn handle_initiate_transfer_token(
let wrapped_token_info: WrappedAssetInfoResponse = let wrapped_token_info: WrappedAssetInfoResponse =
deps.querier.custom_query(&request)?; deps.querier.custom_query(&request)?;
asset_chain = wrapped_token_info.asset_chain; asset_chain = wrapped_token_info.asset_chain;
asset_address = wrapped_token_info.asset_address.into(); asset_address = wrapped_token_info.asset_address.to_array()?;
let transfer_info = TransferInfo {
token_chain: asset_chain,
token_address: asset_address.clone(),
amount: (0, amount.u128()),
recipient_chain,
recipient: recipient.to_vec(),
fee: (0, fee.u128()),
};
let token_bridge_message: TokenBridgeMessage = match transfer_type { let token_bridge_message: TokenBridgeMessage = match transfer_type {
TransferType::WithoutPayload => TokenBridgeMessage { TransferType::WithoutPayload => {
let transfer_info = TransferInfo {
token_chain: asset_chain,
token_address: asset_address,
amount: (0, amount.u128()),
recipient_chain,
recipient,
fee: (0, fee.u128()),
};
TokenBridgeMessage {
action: Action::TRANSFER, action: Action::TRANSFER,
payload: transfer_info.serialize(), payload: transfer_info.serialize(),
},
TransferType::WithPayload { payload } => TokenBridgeMessage {
action: Action::TRANSFER_WITH_PAYLOAD,
payload: TransferWithPayloadInfo {
transfer_info,
payload,
} }
.serialize(), }
}, TransferType::WithPayload { payload } => {
let transfer_info = TransferWithPayloadInfo {
token_chain: asset_chain,
token_address: asset_address,
amount: (0, amount.u128()),
recipient_chain,
recipient,
sender_address,
payload,
};
TokenBridgeMessage {
action: Action::TRANSFER_WITH_PAYLOAD,
payload: transfer_info.serialize(),
}
}
}; };
messages.push(CosmosMsg::Wasm(WasmMsg::Execute { messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
@ -1228,22 +1249,13 @@ fn handle_initiate_transfer_token(
1, 1,
)); ));
asset_address = extend_address_to_32(&asset_canonical); asset_address = extend_address_to_32_array(&asset_canonical);
asset_chain = CHAIN_ID; asset_chain = CHAIN_ID;
// convert to normalized amounts before recording & posting vaa // convert to normalized amounts before recording & posting vaa
amount = Uint128::new(amount.u128().checked_div(multiplier).unwrap()); amount = Uint128::new(amount.u128().checked_div(multiplier).unwrap());
fee = Uint128::new(fee.u128().checked_div(multiplier).unwrap()); fee = Uint128::new(fee.u128().checked_div(multiplier).unwrap());
let transfer_info = TransferInfo {
token_chain: asset_chain,
token_address: asset_address.clone(),
amount: (0, amount.u128()),
recipient_chain,
recipient: recipient.to_vec(),
fee: (0, fee.u128()),
};
// Fetch current CW20 Balance pre-transfer. // Fetch current CW20 Balance pre-transfer.
let balance: BalanceResponse = let balance: BalanceResponse =
deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart {
@ -1264,18 +1276,35 @@ fn handle_initiate_transfer_token(
assert!(wrapped_transfer_tmp(deps.storage).load().is_err()); assert!(wrapped_transfer_tmp(deps.storage).load().is_err());
let token_bridge_message: TokenBridgeMessage = match transfer_type { let token_bridge_message: TokenBridgeMessage = match transfer_type {
TransferType::WithoutPayload => TokenBridgeMessage { TransferType::WithoutPayload => {
let transfer_info = TransferInfo {
amount: (0, amount.u128()),
token_address: asset_address.clone(),
token_chain: asset_chain,
recipient,
recipient_chain,
fee: (0, fee.u128()),
};
TokenBridgeMessage {
action: Action::TRANSFER, action: Action::TRANSFER,
payload: transfer_info.serialize(), payload: transfer_info.serialize(),
},
TransferType::WithPayload { payload } => TokenBridgeMessage {
action: Action::TRANSFER_WITH_PAYLOAD,
payload: TransferWithPayloadInfo {
transfer_info,
payload,
} }
.serialize(), }
}, TransferType::WithPayload { payload } => {
let transfer_info = TransferWithPayloadInfo {
amount: (0, amount.u128()),
token_address: asset_address.clone(),
token_chain: asset_chain,
recipient,
recipient_chain,
sender_address,
payload,
};
TokenBridgeMessage {
action: Action::TRANSFER_WITH_PAYLOAD,
payload: transfer_info.serialize(),
}
}
}; };
// Wrap up state to be captured by the submessage reply. // Wrap up state to be captured by the submessage reply.
@ -1353,36 +1382,46 @@ fn handle_initiate_transfer_native_token(
let mut messages: Vec<CosmosMsg> = vec![]; let mut messages: Vec<CosmosMsg> = vec![];
let asset_chain: u16 = CHAIN_ID; let asset_chain: u16 = CHAIN_ID;
let mut asset_address: Vec<u8> = build_native_id(&denom); let asset_address: CanonicalAddr = build_native_id(&denom).into();
send_native(deps.storage, &asset_address[..].into(), amount)?; send_native(deps.storage, &asset_address, amount)?;
// Mark the first byte of the address to distinguish it as native. // Mark the first byte of the address to distinguish it as native.
asset_address = extend_address_to_32(&asset_address.into()); let mut asset_address = extend_address_to_32_array(&asset_address);
asset_address[0] = 1; asset_address[0] = 1;
let token_bridge_message: TokenBridgeMessage = match transfer_type {
TransferType::WithoutPayload => {
let transfer_info = TransferInfo { let transfer_info = TransferInfo {
token_chain: asset_chain,
token_address: asset_address.to_vec(),
amount: (0, amount.u128()), amount: (0, amount.u128()),
token_address: asset_address,
token_chain: asset_chain,
recipient,
recipient_chain, recipient_chain,
recipient: recipient.to_vec(),
fee: (0, fee.u128()), fee: (0, fee.u128()),
}; };
TokenBridgeMessage {
let token_bridge_message: TokenBridgeMessage = match transfer_type {
TransferType::WithoutPayload => TokenBridgeMessage {
action: Action::TRANSFER, action: Action::TRANSFER,
payload: transfer_info.serialize(), payload: transfer_info.serialize(),
},
TransferType::WithPayload { payload } => TokenBridgeMessage {
action: Action::TRANSFER_WITH_PAYLOAD,
payload: TransferWithPayloadInfo {
transfer_info,
payload,
} }
.serialize(), }
}, TransferType::WithPayload { payload } => {
let sender_address = deps.api.addr_canonicalize(&info.sender.to_string())?;
let sender_address = extend_address_to_32_array(&sender_address);
let transfer_info = TransferWithPayloadInfo {
amount: (0, amount.u128()),
token_address: asset_address,
token_chain: asset_chain,
recipient,
recipient_chain,
sender_address,
payload,
};
TokenBridgeMessage {
action: Action::TRANSFER_WITH_PAYLOAD,
payload: transfer_info.serialize(),
}
}
}; };
let sender = deps.api.addr_canonicalize(&info.sender.as_str())?; let sender = deps.api.addr_canonicalize(&info.sender.as_str())?;
@ -1447,9 +1486,22 @@ fn query_transfer_info(deps: Deps, env: Env, vaa: &Binary) -> StdResult<Transfer
let message = TokenBridgeMessage::deserialize(&data)?; let message = TokenBridgeMessage::deserialize(&data)?;
match message.action { match message.action {
Action::ATTEST_META => ContractError::InvalidVAAAction.std_err(), Action::ATTEST_META => ContractError::InvalidVAAAction.std_err(),
_ => { Action::TRANSFER => {
let core = TransferInfo::deserialize(&message.payload)?;
Ok(TransferInfoResponse {
amount: core.amount.1.into(),
token_address: core.token_address,
token_chain: core.token_chain,
recipient: core.recipient,
recipient_chain: core.recipient_chain,
fee: core.fee.1.into(),
payload: vec![],
})
}
Action::TRANSFER_WITH_PAYLOAD => {
let info = TransferWithPayloadInfo::deserialize(&message.payload)?; let info = TransferWithPayloadInfo::deserialize(&message.payload)?;
let core = info.transfer_info; let core = info.as_transfer_info();
Ok(TransferInfoResponse { Ok(TransferInfoResponse {
amount: core.amount.1.into(), amount: core.amount.1.into(),
@ -1461,6 +1513,7 @@ fn query_transfer_info(deps: Deps, env: Env, vaa: &Binary) -> StdResult<Transfer
payload: info.payload, payload: info.payload,
}) })
} }
other => Err(StdError::generic_err(format!("Invalid action: {}", other))),
} }
} }

View File

@ -89,9 +89,9 @@ pub struct WrappedRegistryResponse {
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub struct TransferInfoResponse { pub struct TransferInfoResponse {
pub amount: Uint128, pub amount: Uint128,
pub token_address: Vec<u8>, pub token_address: [u8; 32],
pub token_chain: u16, pub token_chain: u16,
pub recipient: Vec<u8>, pub recipient: [u8; 32],
pub recipient_chain: u16, pub recipient_chain: u16,
pub fee: Uint128, pub fee: Uint128,
pub payload: Vec<u8>, pub payload: Vec<u8>,

View File

@ -185,9 +185,9 @@ impl TokenBridgeMessage {
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct TransferInfo { pub struct TransferInfo {
pub amount: (u128, u128), pub amount: (u128, u128),
pub token_address: Vec<u8>, pub token_address: [u8; 32],
pub token_chain: u16, pub token_chain: u16,
pub recipient: Vec<u8>, pub recipient: [u8; 32],
pub recipient_chain: u16, pub recipient_chain: u16,
pub fee: (u128, u128), pub fee: (u128, u128),
} }
@ -196,9 +196,9 @@ impl TransferInfo {
pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> { pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
let data = data.as_slice(); let data = data.as_slice();
let amount = data.get_u256(0); let amount = data.get_u256(0);
let token_address = data.get_bytes32(32).to_vec(); let token_address = data.get_const_bytes(32);
let token_chain = data.get_u16(64); let token_chain = data.get_u16(64);
let recipient = data.get_bytes32(66).to_vec(); let recipient = data.get_const_bytes(66);
let recipient_chain = data.get_u16(98); let recipient_chain = data.get_u16(98);
let fee = data.get_u256(100); let fee = data.get_u256(100);
@ -215,7 +215,7 @@ impl TransferInfo {
[ [
self.amount.0.to_be_bytes().to_vec(), self.amount.0.to_be_bytes().to_vec(),
self.amount.1.to_be_bytes().to_vec(), self.amount.1.to_be_bytes().to_vec(),
self.token_address.clone(), self.token_address.to_vec(),
self.token_chain.to_be_bytes().to_vec(), self.token_chain.to_be_bytes().to_vec(),
self.recipient.to_vec(), self.recipient.to_vec(),
self.recipient_chain.to_be_bytes().to_vec(), self.recipient_chain.to_be_bytes().to_vec(),
@ -231,30 +231,72 @@ impl TransferInfo {
// 64 u16 token_chain // 64 u16 token_chain
// 66 [u8; 32] recipient // 66 [u8; 32] recipient
// 98 u16 recipient_chain // 98 u16 recipient_chain
// 100 u256 fee // 100 [u8; 32] sender_address
// 132 [u8] payload // 132 [u8] payload
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct TransferWithPayloadInfo { pub struct TransferWithPayloadInfo {
pub transfer_info: TransferInfo, pub amount: (u128, u128),
pub token_address: [u8; 32],
pub token_chain: u16,
pub recipient: [u8; 32],
pub recipient_chain: u16,
pub sender_address: [u8; 32],
pub payload: Vec<u8>, pub payload: Vec<u8>,
} }
impl TransferWithPayloadInfo { impl TransferWithPayloadInfo {
pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> { pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
let transfer_info = TransferInfo::deserialize(data)?; let data = data.as_slice();
let amount = data.get_u256(0);
let token_address = data.get_const_bytes::<32>(32);
let token_chain = data.get_u16(64);
let recipient = data.get_const_bytes::<32>(66);
let recipient_chain = data.get_u16(98);
let sender_address = data.get_const_bytes::<32>(100);
let payload = TransferWithPayloadInfo::get_payload(data); let payload = TransferWithPayloadInfo::get_payload(data);
Ok(TransferWithPayloadInfo { Ok(TransferWithPayloadInfo {
transfer_info, amount,
token_address,
token_chain,
recipient,
recipient_chain,
sender_address,
payload, payload,
}) })
} }
pub fn serialize(&self) -> Vec<u8> { pub fn serialize(&self) -> Vec<u8> {
[self.transfer_info.serialize(), self.payload.clone()].concat() [
self.amount.0.to_be_bytes().to_vec(),
self.amount.1.to_be_bytes().to_vec(),
self.token_address.to_vec(),
self.token_chain.to_be_bytes().to_vec(),
self.recipient.to_vec(),
self.recipient_chain.to_be_bytes().to_vec(),
self.sender_address.to_vec(),
self.payload.clone(),
]
.concat()
}
pub fn get_payload(data: &[u8]) -> Vec<u8> {
data[132..].to_vec()
}
/// Convert [`TransferWithPayloadInfo`] into [`TransferInfo`] for the
/// purpose of handling them uniformly. Transfers with payload have 0 fees.
pub fn as_transfer_info(&self) -> TransferInfo {
TransferInfo {
amount: self.amount,
token_address: self.token_address.clone(),
token_chain: self.token_chain,
recipient: self.recipient,
recipient_chain: self.recipient_chain,
fee: (0, 0),
} }
pub fn get_payload(data: &Vec<u8>) -> Vec<u8> {
return data[132..].to_vec();
} }
} }

View File

@ -105,7 +105,8 @@ fn deserialize_transfer_vaa() -> StdResult<()> {
let token_address = "0100000000000000000000000000000000000000000000000000000075757364"; let token_address = "0100000000000000000000000000000000000000000000000000000075757364";
let token_address = hex::decode(token_address).unwrap(); let token_address = hex::decode(token_address).unwrap();
assert_eq!( assert_eq!(
info.token_address, token_address, info.token_address.to_vec(),
token_address,
"info.token_address != expected" "info.token_address != expected"
); );
@ -117,7 +118,11 @@ fn deserialize_transfer_vaa() -> StdResult<()> {
let recipient = "000000000000000000000000f7f7dde848e7450a029cd0a9bd9bdae4b5147db3"; let recipient = "000000000000000000000000f7f7dde848e7450a029cd0a9bd9bdae4b5147db3";
let recipient = hex::decode(recipient).unwrap(); let recipient = hex::decode(recipient).unwrap();
assert_eq!(info.recipient, recipient, "info.recipient != expected"); assert_eq!(
info.recipient.to_vec(),
recipient,
"info.recipient != expected"
);
let recipient_chain = 3u16; let recipient_chain = 3u16;
assert_eq!( assert_eq!(
@ -133,15 +138,37 @@ fn deserialize_transfer_vaa() -> StdResult<()> {
#[test] #[test]
fn deserialize_transfer_with_payload_vaa() -> StdResult<()> { fn deserialize_transfer_with_payload_vaa() -> StdResult<()> {
// ┌──────────────────────────────────────────────────────────────────────────────┐
// │ Wormhole VAA v1 │ nonce: 2080370133 │ time: 0 │
// │ guardian set #0 │ #4568529024235897313 │ consistency: 32 │
// ├──────────────────────────────────────────────────────────────────────────────┤
// │ Signature: │
// │ #0: 2565e7ae10421624fd81118855acda893e752aeeef31c13fbfc417591ada... │
// ├──────────────────────────────────────────────────────────────────────────────┤
// │ Emitter: 11111111111111111111111111111115 (Solana) │
// ╞══════════════════════════════════════════════════════════════════════════════╡
// │ Token transfer with payload (aka payload 3) │
// │ Amount: 1.0 │
// │ Token: terra1qqqqqqqqqqqqqqqqqqqqqqqqqp6h2umyswfh6y (Terra) │
// │ Recipient: terra13nkgqrfymug724h8pprpexqj9h629sa3ncw7sh (Terra) │
// │ From: 1399a4e782b935d2bb36b97586d3df8747b07dc66902d807eed0ae99e00ed256 │
// ╞══════════════════════════════════════════════════════════════════════════════╡
// │ Custom payload: │
// │ Length: 30 (0x1e) bytes │
// │ 0000: 41 6c 6c 20 79 6f 75 72 20 62 61 73 65 20 61 72 All your base ar│
// │ 0010: 65 20 62 65 6c 6f 6e 67 20 74 6f 20 75 73 e belong to us │
// └──────────────────────────────────────────────────────────────────────────────┘
let signed_vaa = "\ let signed_vaa = "\
010000000001002b0e392ebe370e718b91dcafbba21094efd8e7f1f12e28bd90\ 010000000001002565e7ae10421624fd81118855acda893e752aeeef31c13fbf\
a178b4dfbbc708675152a3cd2edd20e8e018600026b73b6c6cbf02622903409e\ c417591ada039822195a1321a72cc4bac1c6031e0595f1c1361ca2a30d941a41\
8b48ab7fa30ef001000000010000000100010000000000000000000000000000\ 95fad8020d43d500000000007bffedd500010000000000000000000000000000\
00000000000000000000000000000000ffff0000000000000002000300000000\ 0000000000000000000000000000000000043f66acf143a481e1200300000000\
00000000000000000000000000000000000000000000000005f5e10001000000\ 00000000000000000000000000000000000000000000000005f5e10000000000\
0000000000000000000000000000000000000000000000007575736400030000\ 0000000000000000000000000000000000000000000000007575736400030000\
000000000000000000008cec800d24df11e556e708461c98122df4a2c3b10003\ 000000000000000000008cec800d24df11e556e708461c98122df4a2c3b10003\
00000000000000000000000000000000000000000000000000000000000f4240\ 1399a4e782b935d2bb36b97586d3df8747b07dc66902d807eed0ae99e00ed256\
416c6c20796f75722062617365206172652062656c6f6e6720746f207573"; 416c6c20796f75722062617365206172652062656c6f6e6720746f207573";
let signed_vaa = hex::decode(signed_vaa).unwrap(); let signed_vaa = hex::decode(signed_vaa).unwrap();
@ -153,16 +180,16 @@ fn deserialize_transfer_with_payload_vaa() -> StdResult<()> {
"message.action != expected" "message.action != expected"
); );
let info_with_payload = TransferWithPayloadInfo::deserialize(&message.payload)?; let info = TransferWithPayloadInfo::deserialize(&message.payload)?;
let info = info_with_payload.transfer_info;
let amount = (0u128, 100_000_000u128); let amount = (0u128, 100_000_000u128);
assert_eq!(info.amount, amount, "info.amount != expected"); assert_eq!(info.amount, amount, "info.amount != expected");
let token_address = "0100000000000000000000000000000000000000000000000000000075757364"; let token_address = "0000000000000000000000000000000000000000000000000000000075757364";
let token_address = hex::decode(token_address).unwrap(); let token_address = hex::decode(token_address).unwrap();
assert_eq!( assert_eq!(
info.token_address, token_address, info.token_address.to_vec(),
token_address,
"info.token_address != expected" "info.token_address != expected"
); );
@ -174,7 +201,19 @@ fn deserialize_transfer_with_payload_vaa() -> StdResult<()> {
let recipient = "0000000000000000000000008cec800d24df11e556e708461c98122df4a2c3b1"; let recipient = "0000000000000000000000008cec800d24df11e556e708461c98122df4a2c3b1";
let recipient = hex::decode(recipient).unwrap(); let recipient = hex::decode(recipient).unwrap();
assert_eq!(info.recipient, recipient, "info.recipient != expected"); assert_eq!(
info.recipient.to_vec(),
recipient,
"info.recipient != expected"
);
let sender = "1399a4e782b935d2bb36b97586d3df8747b07dc66902d807eed0ae99e00ed256";
let sender = hex::decode(sender).unwrap();
assert_eq!(
info.sender_address.to_vec(),
sender,
"info.sender != expected"
);
let recipient_chain = 3u16; let recipient_chain = 3u16;
assert_eq!( assert_eq!(
@ -182,13 +221,11 @@ fn deserialize_transfer_with_payload_vaa() -> StdResult<()> {
"info.recipient_chain != expected" "info.recipient_chain != expected"
); );
let fee = (0u128, 1_000_000u128);
assert_eq!(info.fee, fee, "info.fee != expected");
let transfer_payload = "All your base are belong to us"; let transfer_payload = "All your base are belong to us";
let transfer_payload = transfer_payload.as_bytes(); let transfer_payload = transfer_payload.as_bytes();
assert_eq!( assert_eq!(
info_with_payload.payload.as_slice(), info.payload.as_slice(),
transfer_payload, transfer_payload,
"info.payload != expected" "info.payload != expected"
); );

View File

@ -455,7 +455,6 @@ describe("Bridge Tests", () => {
const denom = "uusd"; const denom = "uusd";
const amount = "100000000"; // one benjamin const amount = "100000000"; // one benjamin
const relayerFee = "1000000"; // one dolla
const walletAddress = wallet.key.accAddress; const walletAddress = wallet.key.accAddress;
@ -471,7 +470,7 @@ describe("Bridge Tests", () => {
ustAddress, ustAddress,
encodedTo, encodedTo,
3, 3,
relayerFee, "0",
additionalPayload additionalPayload
); );
console.info("vaaPayload", vaaPayload); console.info("vaaPayload", vaaPayload);
@ -524,33 +523,13 @@ describe("Bridge Tests", () => {
const receipt = await transactWithoutMemo(client, wallet, [submitVaa]); const receipt = await transactWithoutMemo(client, wallet, [submitVaa]);
console.info("receipt txHash", receipt.txhash); console.info("receipt txHash", receipt.txhash);
// check wallet (relayer) balance change
const walletBalanceAfter = await getNativeBalance(
client,
walletAddress,
denom
);
const gasPaid = computeGasPaid(receipt);
const walletExpectedChange = new Int(relayerFee).sub(gasPaid);
// due to rounding, we should expect the balances to reconcile
// within 1 unit (equivalent to 1e-6 uusd). Best-case scenario
// we end up with slightly more balance than expected
const reconciled = walletBalanceAfter
.minus(walletExpectedChange)
.minus(walletBalanceBefore);
expect(
reconciled.greaterThanOrEqualTo("0") &&
reconciled.lessThanOrEqualTo("1")
).toBeTruthy();
// check contract balance change // check contract balance change
const contractBalanceAfter = await getNativeBalance( const contractBalanceAfter = await getNativeBalance(
client, client,
mockBridgeIntegration, mockBridgeIntegration,
denom denom
); );
const contractExpectedChange = new Int(amount).sub(relayerFee); const contractExpectedChange = new Int(amount);
expect( expect(
contractBalanceBefore contractBalanceBefore
.add(contractExpectedChange) .add(contractExpectedChange)