1use crate::{util::slice_data, Error, ParamKind, Token, Word, U256};
13
14use crate::std::Vec;
15
16struct DecodeResult {
17 token: Token,
18 new_offset: usize,
19}
20
21struct BytesTaken {
22 bytes: Vec<u8>,
23 new_offset: usize,
24}
25
26fn as_u32(slice: &Word) -> Result<u32, Error> {
27 if !slice[..28].iter().all(|x| *x == 0) {
28 return Err(Error::InvalidData);
29 }
30
31 let result =
32 ((slice[28] as u32) << 24) + ((slice[29] as u32) << 16) + ((slice[30] as u32) << 8) + (slice[31] as u32);
33
34 Ok(result)
35}
36
37fn as_bool(slice: &Word) -> Result<bool, Error> {
38 if !slice[..31].iter().all(|x| *x == 0) {
39 return Err(Error::InvalidData);
40 }
41
42 Ok(slice[31] == 1)
43}
44
45pub fn decode(types: &[ParamKind], data: &[u8]) -> Result<Vec<Token>, Error> {
47 let is_empty_bytes_valid_encoding = types.iter().all(|t| t.is_empty_bytes_valid_encoding());
48 if !is_empty_bytes_valid_encoding && data.is_empty() {
49 return Err(Error::InvalidName);
50 }
51 let slices = slice_data(data)?;
52 let mut tokens = Vec::with_capacity(types.len());
53 let mut offset = 0;
54 for param in types {
55 let res = decode_param(param, &slices, offset)?;
56 offset = res.new_offset;
57 tokens.push(res.token);
58 }
59 Ok(tokens)
60}
61
62fn peek(slices: &[Word], position: usize) -> Result<&Word, Error> {
63 slices.get(position).ok_or_else(|| Error::InvalidData)
64}
65
66fn take_bytes(slices: &[Word], position: usize, len: usize) -> Result<BytesTaken, Error> {
67 let slices_len = (len + 31) / 32;
68
69 let mut bytes_slices = Vec::with_capacity(slices_len);
70 for i in 0..slices_len {
71 let slice = peek(slices, position + i)?;
72 bytes_slices.push(slice);
73 }
74
75 let bytes = bytes_slices.into_iter().flat_map(|slice| slice.to_vec()).take(len).collect();
76
77 let taken = BytesTaken { bytes, new_offset: position + slices_len };
78
79 Ok(taken)
80}
81
82fn decode_param(param: &ParamKind, slices: &[Word], offset: usize) -> Result<DecodeResult, Error> {
83 match *param {
84 ParamKind::Address => {
85 let slice = peek(slices, offset)?;
86 let mut address = [0u8; 20];
87 address.copy_from_slice(&slice[12..]);
88
89 let result = DecodeResult { token: Token::Address(address.into()), new_offset: offset + 1 };
90
91 Ok(result)
92 }
93 ParamKind::Int(_) => {
94 let slice = peek(slices, offset)?;
95
96 let result = DecodeResult { token: Token::Int(U256::from_big_endian(slice)), new_offset: offset + 1 };
97
98 Ok(result)
99 }
100 ParamKind::Uint(_) => {
101 let slice = peek(slices, offset)?;
102
103 let result = DecodeResult { token: Token::Uint(U256::from_big_endian(slice)), new_offset: offset + 1 };
104
105 Ok(result)
106 }
107 ParamKind::Bool => {
108 let slice = peek(slices, offset)?;
109
110 let b = as_bool(slice)?;
111
112 let result = DecodeResult { token: Token::Bool(b), new_offset: offset + 1 };
113 Ok(result)
114 }
115 ParamKind::FixedBytes(len) => {
116 let taken = take_bytes(slices, offset, len)?;
119 let result = DecodeResult { token: Token::FixedBytes(taken.bytes), new_offset: taken.new_offset };
120 Ok(result)
121 }
122 ParamKind::Bytes => {
123 let offset_slice = peek(slices, offset)?;
124 let len_offset = (as_u32(offset_slice)? / 32) as usize;
125
126 let len_slice = peek(slices, len_offset)?;
127 let len = as_u32(len_slice)? as usize;
128
129 let taken = take_bytes(slices, len_offset + 1, len)?;
130
131 let result = DecodeResult { token: Token::Bytes(taken.bytes), new_offset: offset + 1 };
132 Ok(result)
133 }
134 ParamKind::String => {
135 let offset_slice = peek(slices, offset)?;
136 let len_offset = (as_u32(offset_slice)? / 32) as usize;
137
138 let len_slice = peek(slices, len_offset)?;
139 let len = as_u32(len_slice)? as usize;
140
141 let taken = take_bytes(slices, len_offset + 1, len)?;
142
143 let result = DecodeResult { token: Token::String(taken.bytes), new_offset: offset + 1 };
144 Ok(result)
145 }
146 ParamKind::Array(ref t) => {
147 let offset_slice = peek(slices, offset)?;
148 let len_offset = (as_u32(offset_slice)? / 32) as usize;
149 let len_slice = peek(slices, len_offset)?;
150 let len = as_u32(len_slice)? as usize;
151
152 let tail = &slices[len_offset + 1..];
153 let mut tokens = Vec::with_capacity(len);
154 let mut new_offset = 0;
155
156 for _ in 0..len {
157 let res = decode_param(t, &tail, new_offset)?;
158 new_offset = res.new_offset;
159 tokens.push(res.token);
160 }
161
162 let result = DecodeResult { token: Token::Array(tokens), new_offset: offset + 1 };
163
164 Ok(result)
165 }
166 ParamKind::FixedArray(ref t, len) => {
167 let mut tokens = Vec::with_capacity(len);
168 let is_dynamic = param.is_dynamic();
169
170 let (tail, mut new_offset) = if is_dynamic {
171 (&slices[(as_u32(peek(slices, offset)?)? as usize / 32)..], 0)
172 } else {
173 (slices, offset)
174 };
175
176 for _ in 0..len {
177 let res = decode_param(t, &tail, new_offset)?;
178 new_offset = res.new_offset;
179 tokens.push(res.token);
180 }
181
182 let result = DecodeResult {
183 token: Token::FixedArray(tokens),
184 new_offset: if is_dynamic { offset + 1 } else { new_offset },
185 };
186
187 Ok(result)
188 }
189 ParamKind::Tuple(ref t) => {
190 let is_dynamic = param.is_dynamic();
191
192 let (tail, mut new_offset) = if is_dynamic {
195 (&slices[(as_u32(peek(slices, offset)?)? as usize / 32)..], 0)
196 } else {
197 (slices, offset)
198 };
199
200 let len = t.len();
201 let mut tokens = Vec::with_capacity(len);
202 for i in 0..len {
203 let res = decode_param(&t[i], &tail, new_offset)?;
204 new_offset = res.new_offset;
205 tokens.push(res.token);
206 }
207
208 let result = DecodeResult {
212 token: Token::Tuple(tokens),
213 new_offset: if is_dynamic { offset + 1 } else { new_offset },
214 };
215
216 Ok(result)
217 }
218 }
219}
220
221#[cfg(test)]
222mod tests {
223
224 use crate::{decode, ParamKind, Token, U256};
225 use hex_literal::hex;
226
227 #[test]
228 fn decode_from_empty_byte_slice() {
229 assert!(decode(&[ParamKind::Address], &[]).is_err());
231 assert!(decode(&[ParamKind::Bytes], &[]).is_err());
232 assert!(decode(&[ParamKind::Int(0)], &[]).is_err());
233 assert!(decode(&[ParamKind::Int(1)], &[]).is_err());
234 assert!(decode(&[ParamKind::Int(0)], &[]).is_err());
235 assert!(decode(&[ParamKind::Int(1)], &[]).is_err());
236 assert!(decode(&[ParamKind::Bool], &[]).is_err());
237 assert!(decode(&[ParamKind::String], &[]).is_err());
238 assert!(decode(&[ParamKind::Array(Box::new(ParamKind::Bool))], &[]).is_err());
239 assert!(decode(&[ParamKind::FixedBytes(1)], &[]).is_err());
240 assert!(decode(&[ParamKind::FixedArray(Box::new(ParamKind::Bool), 1)], &[]).is_err());
241
242 assert!(decode(&[ParamKind::FixedBytes(0)], &[]).is_ok());
244 assert!(decode(&[ParamKind::FixedArray(Box::new(ParamKind::Bool), 0)], &[]).is_ok());
245 }
246
247 #[test]
248 fn decode_static_tuple_of_addresses_and_uints() {
249 let encoded = hex!(
250 "
251 0000000000000000000000001111111111111111111111111111111111111111
252 0000000000000000000000002222222222222222222222222222222222222222
253 1111111111111111111111111111111111111111111111111111111111111111
254 "
255 );
256 let address1 = Token::Address([0x11u8; 20].into());
257 let address2 = Token::Address([0x22u8; 20].into());
258 let uint = Token::Uint(U256::from_big_endian(&[0x11u8; 32]));
259 let tuple = Token::Tuple(vec![address1, address2, uint]);
260 let expected = vec![tuple];
261 let decoded = decode(
262 &[ParamKind::Tuple(vec![
263 Box::new(ParamKind::Address),
264 Box::new(ParamKind::Address),
265 Box::new(ParamKind::Uint(32)),
266 ])],
267 &encoded,
268 )
269 .unwrap();
270 assert_eq!(decoded, expected);
271 }
272
273 #[test]
274 fn decode_dynamic_tuple() {
275 let encoded = hex!(
276 "
277 0000000000000000000000000000000000000000000000000000000000000020
278 0000000000000000000000000000000000000000000000000000000000000040
279 0000000000000000000000000000000000000000000000000000000000000080
280 0000000000000000000000000000000000000000000000000000000000000009
281 6761766f66796f726b0000000000000000000000000000000000000000000000
282 0000000000000000000000000000000000000000000000000000000000000009
283 6761766f66796f726b0000000000000000000000000000000000000000000000
284 "
285 );
286 let string1 = Token::String("gavofyork".as_bytes().to_vec());
287 let string2 = Token::String("gavofyork".as_bytes().to_vec());
288 let tuple = Token::Tuple(vec![string1, string2]);
289 let decoded =
290 decode(&[ParamKind::Tuple(vec![Box::new(ParamKind::String), Box::new(ParamKind::String)])], &encoded)
291 .unwrap();
292 let expected = vec![tuple];
293 assert_eq!(decoded, expected);
294 }
295
296 #[test]
297 fn decode_nested_tuple() {
298 let encoded = hex!(
299 "
300 0000000000000000000000000000000000000000000000000000000000000020
301 0000000000000000000000000000000000000000000000000000000000000080
302 0000000000000000000000000000000000000000000000000000000000000001
303 00000000000000000000000000000000000000000000000000000000000000c0
304 0000000000000000000000000000000000000000000000000000000000000100
305 0000000000000000000000000000000000000000000000000000000000000004
306 7465737400000000000000000000000000000000000000000000000000000000
307 0000000000000000000000000000000000000000000000000000000000000006
308 6379626f72670000000000000000000000000000000000000000000000000000
309 0000000000000000000000000000000000000000000000000000000000000060
310 00000000000000000000000000000000000000000000000000000000000000a0
311 00000000000000000000000000000000000000000000000000000000000000e0
312 0000000000000000000000000000000000000000000000000000000000000005
313 6e69676874000000000000000000000000000000000000000000000000000000
314 0000000000000000000000000000000000000000000000000000000000000003
315 6461790000000000000000000000000000000000000000000000000000000000
316 0000000000000000000000000000000000000000000000000000000000000040
317 0000000000000000000000000000000000000000000000000000000000000080
318 0000000000000000000000000000000000000000000000000000000000000004
319 7765656500000000000000000000000000000000000000000000000000000000
320 0000000000000000000000000000000000000000000000000000000000000008
321 66756e7465737473000000000000000000000000000000000000000000000000
322 "
323 );
324 let string1 = Token::String("test".as_bytes().to_vec());
325 let string2 = Token::String("cyborg".as_bytes().to_vec());
326 let string3 = Token::String("night".as_bytes().to_vec());
327 let string4 = Token::String("day".as_bytes().to_vec());
328 let string5 = Token::String("weee".as_bytes().to_vec());
329 let string6 = Token::String("funtests".as_bytes().to_vec());
330 let bool = Token::Bool(true);
331 let deep_tuple = Token::Tuple(vec![string5, string6]);
332 let inner_tuple = Token::Tuple(vec![string3, string4, deep_tuple]);
333 let outer_tuple = Token::Tuple(vec![string1, bool, string2, inner_tuple]);
334 let expected = vec![outer_tuple];
335 let decoded = decode(
336 &[ParamKind::Tuple(vec![
337 Box::new(ParamKind::String),
338 Box::new(ParamKind::Bool),
339 Box::new(ParamKind::String),
340 Box::new(ParamKind::Tuple(vec![
341 Box::new(ParamKind::String),
342 Box::new(ParamKind::String),
343 Box::new(ParamKind::Tuple(vec![Box::new(ParamKind::String), Box::new(ParamKind::String)])),
344 ])),
345 ])],
346 &encoded,
347 )
348 .unwrap();
349 assert_eq!(decoded, expected);
350 }
351
352 #[test]
353 fn decode_complex_tuple_of_dynamic_and_static_types() {
354 let encoded = hex!(
355 "
356 0000000000000000000000000000000000000000000000000000000000000020
357 1111111111111111111111111111111111111111111111111111111111111111
358 0000000000000000000000000000000000000000000000000000000000000080
359 0000000000000000000000001111111111111111111111111111111111111111
360 0000000000000000000000002222222222222222222222222222222222222222
361 0000000000000000000000000000000000000000000000000000000000000009
362 6761766f66796f726b0000000000000000000000000000000000000000000000
363 "
364 );
365 let uint = Token::Uint(U256::from_big_endian(&[0x11u8; 32]));
366 let string = Token::String("gavofyork".as_bytes().to_vec());
367 let address1 = Token::Address([0x11u8; 20].into());
368 let address2 = Token::Address([0x22u8; 20].into());
369 let tuple = Token::Tuple(vec![uint, string, address1, address2]);
370 let expected = vec![tuple];
371 let decoded = decode(
372 &[ParamKind::Tuple(vec![
373 Box::new(ParamKind::Uint(32)),
374 Box::new(ParamKind::String),
375 Box::new(ParamKind::Address),
376 Box::new(ParamKind::Address),
377 ])],
378 &encoded,
379 )
380 .unwrap();
381 assert_eq!(decoded, expected);
382 }
383
384 #[test]
385 fn decode_params_containing_dynamic_tuple() {
386 let encoded = hex!(
387 "
388 0000000000000000000000002222222222222222222222222222222222222222
389 00000000000000000000000000000000000000000000000000000000000000a0
390 0000000000000000000000003333333333333333333333333333333333333333
391 0000000000000000000000004444444444444444444444444444444444444444
392 0000000000000000000000000000000000000000000000000000000000000000
393 0000000000000000000000000000000000000000000000000000000000000001
394 0000000000000000000000000000000000000000000000000000000000000060
395 00000000000000000000000000000000000000000000000000000000000000a0
396 0000000000000000000000000000000000000000000000000000000000000009
397 7370616365736869700000000000000000000000000000000000000000000000
398 0000000000000000000000000000000000000000000000000000000000000006
399 6379626f72670000000000000000000000000000000000000000000000000000
400 "
401 );
402 let address1 = Token::Address([0x22u8; 20].into());
403 let bool1 = Token::Bool(true);
404 let string1 = Token::String("spaceship".as_bytes().to_vec());
405 let string2 = Token::String("cyborg".as_bytes().to_vec());
406 let tuple = Token::Tuple(vec![bool1, string1, string2]);
407 let address2 = Token::Address([0x33u8; 20].into());
408 let address3 = Token::Address([0x44u8; 20].into());
409 let bool2 = Token::Bool(false);
410 let expected = vec![address1, tuple, address2, address3, bool2];
411 let decoded = decode(
412 &[
413 ParamKind::Address,
414 ParamKind::Tuple(vec![
415 Box::new(ParamKind::Bool),
416 Box::new(ParamKind::String),
417 Box::new(ParamKind::String),
418 ]),
419 ParamKind::Address,
420 ParamKind::Address,
421 ParamKind::Bool,
422 ],
423 &encoded,
424 )
425 .unwrap();
426 assert_eq!(decoded, expected);
427 }
428
429 #[test]
430 fn decode_params_containing_static_tuple() {
431 let encoded = hex!(
432 "
433 0000000000000000000000001111111111111111111111111111111111111111
434 0000000000000000000000002222222222222222222222222222222222222222
435 0000000000000000000000000000000000000000000000000000000000000001
436 0000000000000000000000000000000000000000000000000000000000000000
437 0000000000000000000000003333333333333333333333333333333333333333
438 0000000000000000000000004444444444444444444444444444444444444444
439 "
440 );
441 let address1 = Token::Address([0x11u8; 20].into());
442 let address2 = Token::Address([0x22u8; 20].into());
443 let bool1 = Token::Bool(true);
444 let bool2 = Token::Bool(false);
445 let tuple = Token::Tuple(vec![address2, bool1, bool2]);
446 let address3 = Token::Address([0x33u8; 20].into());
447 let address4 = Token::Address([0x44u8; 20].into());
448
449 let expected = vec![address1, tuple, address3, address4];
450 let decoded = decode(
451 &[
452 ParamKind::Address,
453 ParamKind::Tuple(vec![
454 Box::new(ParamKind::Address),
455 Box::new(ParamKind::Bool),
456 Box::new(ParamKind::Bool),
457 ]),
458 ParamKind::Address,
459 ParamKind::Address,
460 ],
461 &encoded,
462 )
463 .unwrap();
464 assert_eq!(decoded, expected);
465 }
466
467 #[test]
468 fn decode_fixed_array_of_strings() {
469 let encoded = hex!(
477 "
478 0000000000000000000000000000000000000000000000000000000000000020
479 0000000000000000000000000000000000000000000000000000000000000040
480 0000000000000000000000000000000000000000000000000000000000000080
481 0000000000000000000000000000000000000000000000000000000000000003
482 666f6f0000000000000000000000000000000000000000000000000000000000
483 0000000000000000000000000000000000000000000000000000000000000003
484 6261720000000000000000000000000000000000000000000000000000000000
485 "
486 );
487
488 let s1 = Token::String("foo".as_bytes().to_vec());
489 let s2 = Token::String("bar".as_bytes().to_vec());
490 let array = Token::FixedArray(vec![s1, s2]);
491
492 let expected = vec![array];
493 let decoded = decode(&[ParamKind::FixedArray(Box::new(ParamKind::String), 2)], &encoded).unwrap();
494
495 assert_eq!(decoded, expected);
496 }
497
498 #[test]
499 fn decode_after_fixed_bytes_with_less_than_32_bytes() {
500 let encoded = hex!(
501 "
502 0000000000000000000000008497afefdc5ac170a664a231f6efb25526ef813f
503 0000000000000000000000000000000000000000000000000000000000000000
504 0000000000000000000000000000000000000000000000000000000000000000
505 0000000000000000000000000000000000000000000000000000000000000080
506 000000000000000000000000000000000000000000000000000000000000000a
507 3078303030303030314600000000000000000000000000000000000000000000
508 "
509 );
510
511 assert_eq!(
512 decode(
513 &[ParamKind::Address, ParamKind::FixedBytes(32), ParamKind::FixedBytes(4), ParamKind::String,],
514 &encoded,
515 )
516 .unwrap(),
517 &[
518 Token::Address(hex!("8497afefdc5ac170a664a231f6efb25526ef813f").into()),
519 Token::FixedBytes([0u8; 32].to_vec()),
520 Token::FixedBytes([0u8; 4].to_vec()),
521 Token::String("0x0000001F".into()),
522 ]
523 );
524 }
525}