terra: Add fromAddress to payload 3
This commit is contained in:
parent
d0900c791a
commit
37ee5cf4a4
|
@ -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))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
);
|
);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue