fix terra vaa parsing

Change-Id: I27306e004897f971d62c82e6046c1f6ec0016247
This commit is contained in:
Hendrik Hofstadt 2021-07-14 19:53:19 +02:00
parent bb446fb338
commit d12863f957
4 changed files with 122 additions and 86 deletions

View File

@ -83,6 +83,7 @@ pub fn handle<S: Storage, A: Api, Q: Querier>(
amount,
recipient_chain,
recipient,
fee,
nonce,
} => handle_initiate_transfer(
deps,
@ -91,6 +92,7 @@ pub fn handle<S: Storage, A: Api, Q: Querier>(
amount,
recipient_chain,
recipient.as_slice().to_vec(),
fee,
nonce,
),
HandleMsg::SubmitVaa { data } => submit_vaa(deps, env, &data),
@ -337,10 +339,13 @@ fn handle_complete_transfer<S: Storage, A: Api, Q: Querier>(
let token_chain = transfer_info.token_chain;
let target_address = (&transfer_info.recipient.as_slice()).get_address(0);
let (not_supported_amount, amount) = transfer_info.amount;
let (not_supported_amount, mut amount) = transfer_info.amount;
let (not_supported_fee, fee) = transfer_info.fee;
amount -= fee;
// Check high 128 bit of amount value to be empty
if not_supported_amount != 0 {
if not_supported_amount != 0 || not_supported_fee != 0 {
return ContractError::AmountTooHigh.std_err();
}
@ -359,15 +364,27 @@ fn handle_complete_transfer<S: Storage, A: Api, Q: Querier>(
.human_address(&target_address)
.or_else(|_| ContractError::WrongTargetAddressFormat.std_err())?;
Ok(HandleResponse {
messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
let mut messages = vec![CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: contract_addr.clone(),
msg: to_binary(&WrappedMsg::Mint {
recipient: recipient.clone(),
amount: Uint128::from(amount),
})?,
send: vec![],
})];
if fee != 0 {
messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: contract_addr.clone(),
msg: to_binary(&WrappedMsg::Mint {
recipient: recipient.clone(),
amount: Uint128::from(amount),
recipient: env.message.sender.clone(),
amount: Uint128::from(fee),
})?,
send: vec![],
})],
}))
}
Ok(HandleResponse {
messages,
log: vec![
log("action", "complete_transfer_wrapped"),
log("contract", contract_addr),
@ -384,15 +401,29 @@ fn handle_complete_transfer<S: Storage, A: Api, Q: Querier>(
let recipient = deps.api.human_address(&target_address)?;
let contract_addr = deps.api.human_address(&token_address)?;
Ok(HandleResponse {
messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
let mut messages = vec![CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: contract_addr.clone(),
msg: to_binary(&TokenMsg::Transfer {
recipient: recipient.clone(),
amount: Uint128::from(amount),
})?,
send: vec![],
})];
if fee != 0 {
messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: contract_addr.clone(),
msg: to_binary(&TokenMsg::Transfer {
recipient: recipient.clone(),
amount: Uint128::from(amount),
recipient: env.message.sender.clone(),
amount: Uint128::from(fee),
})?,
send: vec![],
})],
}))
}
Ok(HandleResponse {
messages,
log: vec![
log("action", "complete_transfer_native"),
log("recipient", recipient),
@ -411,6 +442,7 @@ fn handle_initiate_transfer<S: Storage, A: Api, Q: Querier>(
amount: Uint128,
recipient_chain: u16,
recipient: Vec<u8>,
fee: Uint128,
nonce: u32,
) -> StdResult<HandleResponse> {
// if recipient_chain == CHAIN_ID {
@ -421,6 +453,10 @@ fn handle_initiate_transfer<S: Storage, A: Api, Q: Querier>(
return ContractError::AmountTooLow.std_err();
}
if fee > amount {
return Err(StdError::generic_err("fee greater than sent amount"))
}
let asset_chain: u16;
let asset_address: Vec<u8>;
@ -471,6 +507,7 @@ fn handle_initiate_transfer<S: Storage, A: Api, Q: Querier>(
amount: (0, amount.u128()),
recipient_chain,
recipient: recipient.clone(),
fee: (0, fee.u128()),
};
let token_bridge_message = TokenBridgeMessage {

View File

@ -24,6 +24,7 @@ pub enum HandleMsg {
amount: Uint128,
recipient_chain: u16,
recipient: Binary,
fee: Uint128,
nonce: u32,
},

View File

@ -89,65 +89,65 @@ impl TokenBridgeMessage {
}
}
// 0 u16 token_chain
// 2 [u8; 32] token_address
// 34 u256 amount
// 66 u16 recipient_chain
// 68 [u8; 32] recipient
// 0 u256 amount
// 32 [u8; 32] token_address
// 64 u16 token_chain
// 66 [u8; 32] recipient
// 98 u16 recipient_chain
// 100 u256 fee
pub struct TransferInfo {
pub token_chain: u16,
pub token_address: Vec<u8>,
pub amount: (u128, u128),
pub token_address: Vec<u8>,
pub token_chain: u16,
pub recipient_chain: u16,
pub recipient: Vec<u8>,
pub fee: (u128, u128),
}
impl TransferInfo {
pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
let data = data.as_slice();
let token_chain = data.get_u16(0);
let token_address = data.get_bytes32(2).to_vec();
let amount = data.get_u256(34);
let recipient_chain = data.get_u16(66);
let recipient = data.get_bytes32(68).to_vec();
let amount = data.get_u256(0);
let token_address = data.get_bytes32(32).to_vec();
let token_chain = data.get_u16(64);
let recipient = data.get_bytes32(66).to_vec();
let recipient_chain = data.get_u16(98);
let fee = data.get_u256(100);
Ok(TransferInfo {
token_chain,
token_address,
amount,
recipient_chain,
token_address,
token_chain,
recipient,
recipient_chain,
fee,
})
}
pub fn serialize(&self) -> Vec<u8> {
[
self.token_chain.to_be_bytes().to_vec(),
self.token_address.clone(),
self.amount.0.to_be_bytes().to_vec(),
self.amount.1.to_be_bytes().to_vec(),
self.recipient_chain.to_be_bytes().to_vec(),
self.token_address.clone(),
self.token_chain.to_be_bytes().to_vec(),
self.recipient.to_vec(),
self.recipient_chain.to_be_bytes().to_vec(),
self.fee.0.to_be_bytes().to_vec(),
self.fee.1.to_be_bytes().to_vec(),
]
.concat()
}
}
//PayloadID uint8 = 2
// // Address of the token. Left-zero-padded if shorter than 32 bytes
// TokenAddress [32]uint8
// // Chain ID of the token
// TokenChain uint16
// // Number of decimals of the token
// Decimals uint8
// // Symbol of the token (UTF-8)
// Symbol [32]uint8
// // Name of the token (UTF-8)
// Name [32]uint8
// 0 [32]uint8 TokenAddress
// 32 uint16 TokenChain
// 34 uint8 Decimals
// 35 [32]uint8 Symbol
// 67 [32]uint8 Name
pub struct AssetMeta {
pub token_chain: u16,
pub token_address: Vec<u8>,
pub token_chain: u16,
pub decimals: u8,
pub symbol: Vec<u8>,
pub name: Vec<u8>,
@ -156,8 +156,8 @@ pub struct AssetMeta {
impl AssetMeta {
pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
let data = data.as_slice();
let token_chain = data.get_u16(0);
let token_address = data.get_bytes32(2).to_vec();
let token_address = data.get_bytes32(0).to_vec();
let token_chain = data.get_u16(32);
let decimals = data.get_u8(34);
let symbol = data.get_bytes32(35).to_vec();
let name = data.get_bytes32(67).to_vec();
@ -173,8 +173,8 @@ impl AssetMeta {
pub fn serialize(&self) -> Vec<u8> {
[
self.token_chain.to_be_bytes().to_vec(),
self.token_address.clone(),
self.token_chain.to_be_bytes().to_vec(),
self.decimals.to_be_bytes().to_vec(),
self.symbol.clone(),
self.name.clone(),

View File

@ -42,7 +42,7 @@ pub struct ConfigInfo {
pub struct ParsedVAA {
pub version: u8,
pub guardian_set_index: u32,
pub timestamp: u64,
pub timestamp: u32,
pub nonce: u32,
pub len_signers: u8,
@ -68,13 +68,13 @@ impl ParsedVAA {
1 [65]uint8 signature
body:
0 uint64 timestamp (unix in seconds)
8 uint32 nonce
12 uint16 emitter_chain
14 [32]uint8 emitter_address
46 uint64 sequence
46 uint8 consistency_level
54 []uint8 payload
0 uint32 timestamp (unix in seconds)
4 uint32 nonce
8 uint16 emitter_chain
10 [32]uint8 emitter_address
42 uint64 sequence
50 uint8 consistency_level
51 []uint8 payload
*/
pub const HEADER_LEN: usize = 6;
@ -83,12 +83,12 @@ impl ParsedVAA {
pub const GUARDIAN_SET_INDEX_POS: usize = 1;
pub const LEN_SIGNER_POS: usize = 5;
pub const VAA_NONCE_POS: usize = 8;
pub const VAA_EMITTER_CHAIN_POS: usize = 12;
pub const VAA_EMITTER_ADDRESS_POS: usize = 14;
pub const VAA_SEQUENCE_POS: usize = 46;
pub const VAA_CONSISTENCY_LEVEL_POS: usize = 54;
pub const VAA_PAYLOAD_POS: usize = 55;
pub const VAA_NONCE_POS: usize = 4;
pub const VAA_EMITTER_CHAIN_POS: usize = 8;
pub const VAA_EMITTER_ADDRESS_POS: usize = 10;
pub const VAA_SEQUENCE_POS: usize = 42;
pub const VAA_CONSISTENCY_LEVEL_POS: usize = 50;
pub const VAA_PAYLOAD_POS: usize = 51;
// Signature data offsets in the signature block
pub const SIG_DATA_POS: usize = 1;
@ -124,7 +124,7 @@ impl ParsedVAA {
return ContractError::InvalidVAA.std_err();
}
let timestamp = data.get_u64(body_offset);
let timestamp = data.get_u32(body_offset);
let nonce = data.get_u32(body_offset + Self::VAA_NONCE_POS);
let emitter_chain = data.get_u16(body_offset + Self::VAA_EMITTER_CHAIN_POS);
let emitter_address = data
@ -402,31 +402,29 @@ mod tests {
#[test]
fn test_deserialize() {
let x = vec![
1u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 96u8, 180u8, 80u8, 111u8, 0u8, 0u8,
0u8, 1u8, 0u8, 3u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 120u8,
73u8, 153u8, 19u8, 90u8, 170u8, 138u8, 60u8, 165u8, 145u8, 68u8, 104u8, 133u8, 47u8,
221u8, 219u8, 221u8, 216u8, 120u8, 157u8, 0u8, 91u8, 48u8, 44u8, 48u8, 44u8, 51u8,
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 53u8, 54u8, 44u8,
50u8, 51u8, 51u8, 44u8, 49u8, 44u8, 49u8, 49u8, 49u8, 44u8, 49u8, 54u8, 55u8, 44u8,
49u8, 57u8, 48u8, 44u8, 50u8, 48u8, 51u8, 44u8, 49u8, 54u8, 44u8, 49u8, 55u8, 54u8,
44u8, 50u8, 49u8, 56u8, 44u8, 50u8, 53u8, 49u8, 44u8, 49u8, 51u8, 49u8, 44u8, 51u8,
57u8, 44u8, 49u8, 54u8, 44u8, 49u8, 57u8, 53u8, 44u8, 50u8, 50u8, 55u8, 44u8, 49u8,
52u8, 57u8, 44u8, 50u8, 51u8, 54u8, 44u8, 49u8, 57u8, 48u8, 44u8, 50u8, 49u8, 50u8,
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
44u8, 48u8, 44u8, 48u8, 44u8, 51u8, 44u8, 50u8, 51u8, 50u8, 44u8, 48u8, 44u8, 51u8,
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 53u8, 51u8, 44u8,
49u8, 49u8, 54u8, 44u8, 52u8, 56u8, 44u8, 49u8, 49u8, 54u8, 44u8, 49u8, 52u8, 57u8,
44u8, 49u8, 48u8, 56u8, 44u8, 49u8, 49u8, 51u8, 44u8, 56u8, 44u8, 48u8, 44u8, 50u8,
51u8, 50u8, 44u8, 52u8, 57u8, 44u8, 49u8, 53u8, 50u8, 44u8, 49u8, 44u8, 50u8, 56u8,
44u8, 50u8, 48u8, 51u8, 44u8, 50u8, 49u8, 50u8, 44u8, 50u8, 50u8, 49u8, 44u8, 50u8,
52u8, 49u8, 44u8, 56u8, 53u8, 44u8, 49u8, 48u8, 57u8, 93u8,
];
ParsedVAA::deserialize(x.as_slice()).unwrap();
let x = hex::decode("080000000901007bfa71192f886ab6819fa4862e34b4d178962958d9b2e3d9437338c9e5fde1443b809d2886eaa69e0f0158ea517675d96243c9209c3fe1d94d5b19866654c6980000000b150000000500020001020304000000000000000000000000000000000000000000000000000000000000000000000a0261626364").unwrap();
let v = ParsedVAA::deserialize(x.as_slice()).unwrap();
assert_eq!(
v,
ParsedVAA {
version: 8,
guardian_set_index: 9,
timestamp: 2837,
nonce: 5,
len_signers: 1,
emitter_chain: 2,
emitter_address: vec![
0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0
],
sequence: 10,
consistency_level: 2,
payload: vec![97, 98, 99, 100],
hash: vec![
195, 10, 19, 96, 8, 61, 218, 69, 160, 238, 165, 142, 105, 119, 139, 121, 212,
73, 238, 179, 13, 80, 245, 224, 75, 110, 163, 8, 185, 132, 55, 34
]
}
);
}
}