abi_decode.rs 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::solana_tests::abi_encode::create_response;
  3. use crate::{build_solidity, BorshToken};
  4. use borsh::BorshSerialize;
  5. #[test]
  6. fn integers_bool_enum() {
  7. #[derive(BorshSerialize, PartialEq, Eq, Debug)]
  8. #[allow(unused)]
  9. enum WeekDay {
  10. Sunday,
  11. Monday,
  12. Tuesday,
  13. Wednesday,
  14. Thursday,
  15. Friday,
  16. Saturday,
  17. }
  18. #[derive(BorshSerialize, Debug)]
  19. struct Res1 {
  20. a: u8,
  21. b: u64,
  22. c: u128,
  23. d: i16,
  24. e: i32,
  25. day: WeekDay,
  26. h: bool,
  27. }
  28. #[derive(BorshSerialize, Debug)]
  29. struct Res2 {
  30. item_1: WeekDay,
  31. item_2: WeekDay,
  32. item_3: WeekDay,
  33. }
  34. let mut vm = build_solidity(
  35. r#"
  36. contract Testing {
  37. enum WeekDay {
  38. Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
  39. }
  40. function decodeTest1(bytes memory buffer) public pure {
  41. (uint8 a, uint64 b, uint128 c, int16 d, int32 e, WeekDay day, bool h) =
  42. abi.decode(buffer, (uint8, uint64, uint128, int16, int32, WeekDay, bool));
  43. assert(a == 45);
  44. assert(b == 9965956609890);
  45. assert(c == 88);
  46. assert(d == -29);
  47. assert(e == -88);
  48. assert(day == WeekDay.Wednesday);
  49. assert(h == false);
  50. }
  51. function decodeTest2(bytes memory buffer) public pure {
  52. (WeekDay a, WeekDay b, WeekDay c) =
  53. abi.decode(buffer, (WeekDay, WeekDay, WeekDay));
  54. assert(a == WeekDay.Sunday);
  55. assert(b == WeekDay.Saturday);
  56. assert(c == WeekDay.Friday);
  57. }
  58. }
  59. "#,
  60. );
  61. let data_account = vm.initialize_data_account();
  62. vm.function("new")
  63. .accounts(vec![("dataAccount", data_account)])
  64. .call();
  65. let input = Res1 {
  66. a: 45,
  67. b: 9965956609890,
  68. c: 88,
  69. d: -29,
  70. e: -88,
  71. day: WeekDay::Wednesday,
  72. h: false,
  73. };
  74. let encoded = input.try_to_vec().unwrap();
  75. let _ = vm
  76. .function("decodeTest1")
  77. .arguments(&[BorshToken::Bytes(encoded)])
  78. .call();
  79. let input = Res2 {
  80. item_1: WeekDay::Sunday,
  81. item_2: WeekDay::Saturday,
  82. item_3: WeekDay::Friday,
  83. };
  84. let encoded = input.try_to_vec().unwrap();
  85. let _ = vm
  86. .function("decodeTest2")
  87. .arguments(&[BorshToken::Bytes(encoded)])
  88. .call();
  89. }
  90. #[test]
  91. fn decode_address() {
  92. #[derive(BorshSerialize, Debug)]
  93. struct Data {
  94. address: [u8; 32],
  95. this: [u8; 32],
  96. }
  97. let mut vm = build_solidity(
  98. r#"
  99. contract Testing {
  100. function testAddress(bytes memory buffer) public view {
  101. (address a, Testing b) = abi.decode(buffer, (address, Testing));
  102. assert(a == address(this));
  103. assert(b == this);
  104. }
  105. }
  106. "#,
  107. );
  108. let data_account = vm.initialize_data_account();
  109. vm.function("new")
  110. .accounts(vec![("dataAccount", data_account)])
  111. .call();
  112. let input = Data {
  113. address: data_account,
  114. this: data_account,
  115. };
  116. let encoded = input.try_to_vec().unwrap();
  117. let _ = vm
  118. .function("testAddress")
  119. .arguments(&[BorshToken::Bytes(encoded)])
  120. .accounts(vec![("dataAccount", data_account)])
  121. .call();
  122. }
  123. #[test]
  124. fn string_and_bytes() {
  125. #[derive(BorshSerialize, Debug)]
  126. struct Data {
  127. a: String,
  128. b: Vec<u8>,
  129. }
  130. let mut vm = build_solidity(
  131. r#"
  132. contract Testing {
  133. function testStringAndBytes(bytes memory buffer) public view {
  134. (string memory a, bytes memory b) = abi.decode(buffer, (string, bytes));
  135. assert(a == "coffee");
  136. assert(b == "tea");
  137. }
  138. }
  139. "#,
  140. );
  141. let data_account = vm.initialize_data_account();
  142. vm.function("new")
  143. .accounts(vec![("dataAccount", data_account)])
  144. .call();
  145. let data = Data {
  146. a: "coffee".to_string(),
  147. b: b"tea".to_vec(),
  148. };
  149. let encoded = data.try_to_vec().unwrap();
  150. let _ = vm
  151. .function("testStringAndBytes")
  152. .arguments(&[BorshToken::Bytes(encoded)])
  153. .accounts(vec![("dataAccount", data_account)])
  154. .call();
  155. }
  156. #[test]
  157. fn primitive_struct() {
  158. #[derive(Debug, BorshSerialize)]
  159. struct NoPadStruct {
  160. a: u32,
  161. b: u32,
  162. }
  163. #[derive(Debug, BorshSerialize)]
  164. struct PaddedStruct {
  165. a: u128,
  166. b: u8,
  167. c: [u8; 32],
  168. }
  169. let mut vm = build_solidity(
  170. r#"
  171. contract Testing {
  172. struct NoPadStruct {
  173. uint32 a;
  174. uint32 b;
  175. }
  176. struct PaddedStruct {
  177. uint128 a;
  178. uint8 b;
  179. bytes32 c;
  180. }
  181. function testNoPadStruct(bytes memory buffer) public pure {
  182. NoPadStruct memory str = abi.decode(buffer, (NoPadStruct));
  183. assert(str.a == 1238);
  184. assert(str.b == 87123);
  185. }
  186. function testPaddedStruct(bytes memory buffer) public pure {
  187. PaddedStruct memory str = abi.decode(buffer, (PaddedStruct));
  188. assert(str.a == 12998);
  189. assert(str.b == 240);
  190. assert(str.c == "tea_is_good");
  191. }
  192. }
  193. "#,
  194. );
  195. let data_account = vm.initialize_data_account();
  196. vm.function("new")
  197. .accounts(vec![("dataAccount", data_account)])
  198. .call();
  199. let data = NoPadStruct { a: 1238, b: 87123 };
  200. let encoded = data.try_to_vec().unwrap();
  201. let _ = vm
  202. .function("testNoPadStruct")
  203. .arguments(&[BorshToken::Bytes(encoded)])
  204. .call();
  205. let mut elem = b"tea_is_good".to_vec();
  206. elem.append(&mut vec![0; 21]);
  207. let data = PaddedStruct {
  208. a: 12998,
  209. b: 240,
  210. c: <[u8; 32]>::try_from(&elem[0..32]).unwrap(),
  211. };
  212. let encoded = data.try_to_vec().unwrap();
  213. let _ = vm
  214. .function("testPaddedStruct")
  215. .arguments(&[BorshToken::Bytes(encoded)])
  216. .call();
  217. }
  218. #[test]
  219. fn returned_string() {
  220. #[derive(Debug, BorshSerialize)]
  221. struct Input {
  222. rr: String,
  223. }
  224. let mut vm = build_solidity(
  225. r#"
  226. contract Testing {
  227. function returnedString(bytes memory buffer) public pure returns (string memory) {
  228. string memory s = abi.decode(buffer, (string));
  229. return s;
  230. }
  231. }
  232. "#,
  233. );
  234. let data_account = vm.initialize_data_account();
  235. vm.function("new")
  236. .accounts(vec![("dataAccount", data_account)])
  237. .call();
  238. let data = Input {
  239. rr: "cortado".to_string(),
  240. };
  241. let encoded = data.try_to_vec().unwrap();
  242. let returns = vm
  243. .function("returnedString")
  244. .arguments(&[BorshToken::Bytes(encoded)])
  245. .call()
  246. .unwrap();
  247. let string = returns.into_string().unwrap();
  248. assert_eq!(string, "cortado");
  249. }
  250. #[test]
  251. fn test_string_array() {
  252. #[derive(Debug, BorshSerialize)]
  253. struct Input {
  254. a: Vec<String>,
  255. }
  256. let mut vm = build_solidity(
  257. r#"
  258. contract Testing {
  259. function testStringVector(bytes memory buffer) public pure returns (string[] memory) {
  260. string[] memory vec = abi.decode(buffer, (string[]));
  261. return vec;
  262. }
  263. }
  264. "#,
  265. );
  266. let data_account = vm.initialize_data_account();
  267. vm.function("new")
  268. .accounts(vec![("dataAccount", data_account)])
  269. .call();
  270. let data = Input {
  271. a: vec![
  272. "coffee".to_string(),
  273. "tea".to_string(),
  274. "cappuccino".to_string(),
  275. ],
  276. };
  277. let encoded = data.try_to_vec().unwrap();
  278. let returns = vm
  279. .function("testStringVector")
  280. .arguments(&[BorshToken::Bytes(encoded)])
  281. .call()
  282. .unwrap();
  283. let vec = returns.into_array().unwrap();
  284. assert_eq!(vec.len(), 3);
  285. assert_eq!(vec[0].clone().into_string().unwrap(), "coffee");
  286. assert_eq!(vec[1].clone().into_string().unwrap(), "tea");
  287. assert_eq!(vec[2].clone().into_string().unwrap(), "cappuccino");
  288. }
  289. #[test]
  290. fn struct_within_struct() {
  291. #[derive(Debug, BorshSerialize)]
  292. struct NoPadStruct {
  293. a: u32,
  294. b: u32,
  295. }
  296. #[derive(Debug, BorshSerialize)]
  297. struct PaddedStruct {
  298. a: u128,
  299. b: u8,
  300. c: [u8; 32],
  301. }
  302. #[derive(Debug, BorshSerialize)]
  303. struct NonConstantStruct {
  304. a: u64,
  305. b: Vec<String>,
  306. no_pad: NoPadStruct,
  307. pad: PaddedStruct,
  308. }
  309. let mut vm = build_solidity(
  310. r#"
  311. contract Testing {
  312. struct noPadStruct {
  313. uint32 a;
  314. uint32 b;
  315. }
  316. struct PaddedStruct {
  317. uint128 a;
  318. uint8 b;
  319. bytes32 c;
  320. }
  321. struct NonConstantStruct {
  322. uint64 a;
  323. string[] b;
  324. noPadStruct noPad;
  325. PaddedStruct pad;
  326. }
  327. function testStruct(bytes memory buffer) public pure {
  328. NonConstantStruct memory str = abi.decode(buffer, (NonConstantStruct));
  329. assert(str.a == 890234);
  330. assert(str.b.length == 2);
  331. assert(str.b[0] == "tea");
  332. assert(str.b[1] == "coffee");
  333. assert(str.noPad.a == 89123);
  334. assert(str.noPad.b == 12354);
  335. assert(str.pad.a == 988834);
  336. assert(str.pad.b == 129);
  337. assert(str.pad.c == "tea_is_good");
  338. }
  339. }
  340. "#,
  341. );
  342. let data_account = vm.initialize_data_account();
  343. vm.function("new")
  344. .accounts(vec![("dataAccount", data_account)])
  345. .call();
  346. let no_pad = NoPadStruct { a: 89123, b: 12354 };
  347. let mut tea_is_good = b"tea_is_good".to_vec();
  348. tea_is_good.append(&mut vec![0; 21]);
  349. let pad = PaddedStruct {
  350. a: 988834,
  351. b: 129,
  352. c: <[u8; 32]>::try_from(tea_is_good).unwrap(),
  353. };
  354. let data = NonConstantStruct {
  355. a: 890234,
  356. b: vec!["tea".to_string(), "coffee".to_string()],
  357. no_pad,
  358. pad,
  359. };
  360. let encoded = data.try_to_vec().unwrap();
  361. let _ = vm
  362. .function("testStruct")
  363. .arguments(&[BorshToken::Bytes(encoded)])
  364. .call();
  365. }
  366. #[test]
  367. fn struct_in_array() {
  368. #[derive(Debug, BorshSerialize)]
  369. struct NoPadStruct {
  370. a: u32,
  371. b: u32,
  372. }
  373. #[derive(Debug, BorshSerialize)]
  374. struct PaddedStruct {
  375. a: u128,
  376. b: u8,
  377. c: [u8; 32],
  378. }
  379. #[derive(Debug, BorshSerialize)]
  380. struct Input1 {
  381. item_1: NoPadStruct,
  382. item_2: PaddedStruct,
  383. }
  384. #[derive(Debug, BorshSerialize)]
  385. struct Input2 {
  386. item_1: [i32; 4],
  387. item_2: [NoPadStruct; 2],
  388. item_3: Vec<NoPadStruct>,
  389. }
  390. #[derive(Debug, BorshSerialize)]
  391. struct Input3 {
  392. vec: Vec<NoPadStruct>,
  393. }
  394. let mut vm = build_solidity(
  395. r#"
  396. contract Testing {
  397. struct NoPadStruct {
  398. uint32 a;
  399. uint32 b;
  400. }
  401. struct PaddedStruct {
  402. uint128 a;
  403. uint8 b;
  404. bytes32 c;
  405. }
  406. function twoStructs(bytes memory buffer) public pure {
  407. (NoPadStruct memory a, PaddedStruct memory b) = abi.decode(buffer, (NoPadStruct, PaddedStruct));
  408. assert(a.a == 945);
  409. assert(a.b == 7453);
  410. assert(b.a == 1);
  411. assert(b.b == 3);
  412. assert(b.c == "there_is_padding_here");
  413. }
  414. function fixedArrays(bytes memory buffer) public pure {
  415. (int32[4] memory a, NoPadStruct[2] memory b, NoPadStruct[] memory c) =
  416. abi.decode(buffer, (int32[4], NoPadStruct[2], NoPadStruct[]));
  417. assert(a[0] == 1);
  418. assert(a[1] == -298);
  419. assert(a[2] == 3);
  420. assert(a[3] == -434);
  421. assert(b[0].a == 1);
  422. assert(b[0].b == 2);
  423. assert(b[1].a == 3);
  424. assert(b[1].b == 4);
  425. assert(c.length == 3);
  426. assert(c[0].a == 1623);
  427. assert(c[0].b == 43279);
  428. assert(c[1].a == 41234);
  429. assert(c[1].b == 98375);
  430. assert(c[2].a == 945);
  431. assert(c[2].b == 7453);
  432. }
  433. function primitiveDynamic(bytes memory buffer) public pure {
  434. NoPadStruct[] memory vec = abi.decode(buffer, (NoPadStruct[]));
  435. assert(vec.length == 2);
  436. assert(vec[0].a == 5);
  437. assert(vec[0].b == 6);
  438. assert(vec[1].a == 7);
  439. assert(vec[1].b == 8);
  440. }
  441. }
  442. "#,
  443. );
  444. let data_account = vm.initialize_data_account();
  445. vm.function("new")
  446. .accounts(vec![("dataAccount", data_account)])
  447. .call();
  448. let mut bytes_string = b"there_is_padding_here".to_vec();
  449. bytes_string.append(&mut vec![0; 11]);
  450. let input = Input1 {
  451. item_1: NoPadStruct { a: 945, b: 7453 },
  452. item_2: PaddedStruct {
  453. a: 1,
  454. b: 3,
  455. c: <[u8; 32]>::try_from(bytes_string).unwrap(),
  456. },
  457. };
  458. let encoded = input.try_to_vec().unwrap();
  459. let _ = vm
  460. .function("twoStructs")
  461. .arguments(&[BorshToken::Bytes(encoded)])
  462. .call();
  463. let input = Input2 {
  464. item_1: [1, -298, 3, -434],
  465. item_2: [NoPadStruct { a: 1, b: 2 }, NoPadStruct { a: 3, b: 4 }],
  466. item_3: vec![
  467. NoPadStruct { a: 1623, b: 43279 },
  468. NoPadStruct { a: 41234, b: 98375 },
  469. NoPadStruct { a: 945, b: 7453 },
  470. ],
  471. };
  472. let encoded = input.try_to_vec().unwrap();
  473. let _ = vm
  474. .function("fixedArrays")
  475. .arguments(&[BorshToken::Bytes(encoded)])
  476. .call();
  477. let input = Input3 {
  478. vec: vec![NoPadStruct { a: 5, b: 6 }, NoPadStruct { a: 7, b: 8 }],
  479. };
  480. let encoded = input.try_to_vec().unwrap();
  481. let _ = vm
  482. .function("primitiveDynamic")
  483. .arguments(&[BorshToken::Bytes(encoded)])
  484. .call();
  485. }
  486. #[test]
  487. fn arrays() {
  488. #[derive(Debug, BorshSerialize, Default, Clone)]
  489. struct NonConstantStruct {
  490. a: u64,
  491. b: Vec<String>,
  492. }
  493. #[derive(Debug, BorshSerialize)]
  494. struct Input1 {
  495. complex_array: Vec<NonConstantStruct>,
  496. }
  497. #[derive(Debug, BorshSerialize)]
  498. struct Input2 {
  499. vec: Vec<i16>,
  500. }
  501. #[derive(Debug, BorshSerialize)]
  502. struct Input3 {
  503. multi_dim: [[i8; 2]; 3],
  504. }
  505. let mut vm = build_solidity(
  506. r#"
  507. contract Testing {
  508. struct NonConstantStruct {
  509. uint64 a;
  510. string[] b;
  511. }
  512. function decodeComplex(bytes memory buffer) public view {
  513. NonConstantStruct[] memory vec = abi.decode(buffer, (NonConstantStruct[]));
  514. assert(vec.length == 2);
  515. assert(vec[0].a == 897);
  516. assert(vec[0].b[0] == "tea");
  517. assert(vec[0].b[1] == "coffee");
  518. assert(vec[1].a == 74123);
  519. assert(vec[1].b[0] == "cortado");
  520. assert(vec[1].b[1] == "cappuccino");
  521. }
  522. function dynamicArray(bytes memory buffer) public view {
  523. int16[] memory vec = abi.decode(buffer, (int16[]));
  524. assert(vec.length == 3);
  525. assert(vec[0] == -90);
  526. assert(vec[1] == 5523);
  527. assert(vec[2] == -89);
  528. }
  529. function decodeMultiDim(bytes memory buffer) public view {
  530. int8[2][3] memory vec = abi.decode(buffer, (int8[2][3]));
  531. print("{}".format(vec[0][1]));
  532. assert(vec[0][0] == 1);
  533. assert(vec[0][1] == 2);
  534. assert(vec[1][0] == 4);
  535. assert(vec[1][1] == 5);
  536. assert(vec[2][0] == 6);
  537. assert(vec[2][1] == 7);
  538. }
  539. }
  540. "#,
  541. );
  542. let data_account = vm.initialize_data_account();
  543. vm.function("new")
  544. .accounts(vec![("dataAccount", data_account)])
  545. .call();
  546. let input = Input1 {
  547. complex_array: vec![
  548. NonConstantStruct {
  549. a: 897,
  550. b: vec!["tea".to_string(), "coffee".to_string()],
  551. },
  552. NonConstantStruct {
  553. a: 74123,
  554. b: vec!["cortado".to_string(), "cappuccino".to_string()],
  555. },
  556. ],
  557. };
  558. let encoded = input.try_to_vec().unwrap();
  559. let _ = vm
  560. .function("decodeComplex")
  561. .arguments(&[BorshToken::Bytes(encoded)])
  562. .accounts(vec![("dataAccount", data_account)])
  563. .call();
  564. let input = Input2 {
  565. vec: vec![-90, 5523, -89],
  566. };
  567. let encoded = input.try_to_vec().unwrap();
  568. let _ = vm
  569. .function("dynamicArray")
  570. .arguments(&[BorshToken::Bytes(encoded)])
  571. .accounts(vec![("dataAccount", data_account)])
  572. .call();
  573. let input = Input3 {
  574. multi_dim: [[1, 2], [4, 5], [6, 7]],
  575. };
  576. let encoded = input.try_to_vec().unwrap();
  577. let _ = vm
  578. .function("decodeMultiDim")
  579. .arguments(&[BorshToken::Bytes(encoded)])
  580. .accounts(vec![("dataAccount", data_account)])
  581. .call();
  582. }
  583. #[test]
  584. fn multi_dimensional_arrays() {
  585. #[derive(Debug, BorshSerialize)]
  586. struct PaddedStruct {
  587. a: u128,
  588. b: u8,
  589. c: [u8; 32],
  590. }
  591. #[derive(Debug, BorshSerialize)]
  592. struct Input1 {
  593. item_1: Vec<[[PaddedStruct; 2]; 3]>,
  594. item_2: i16,
  595. }
  596. #[derive(Debug, BorshSerialize)]
  597. struct Input2 {
  598. vec: Vec<[[u16; 4]; 2]>,
  599. }
  600. #[derive(Debug, BorshSerialize)]
  601. struct Input3 {
  602. vec: Vec<u16>,
  603. }
  604. let mut vm = build_solidity(
  605. r#"
  606. contract Testing {
  607. struct PaddedStruct {
  608. uint128 a;
  609. uint8 b;
  610. bytes32 c;
  611. }
  612. function multiDimStruct(bytes memory buffer) public pure {
  613. (PaddedStruct[2][3][] memory vec, int16 g) = abi.decode(buffer, (PaddedStruct[2][3][], int16));
  614. assert(vec.length == 1);
  615. assert(vec[0][0][0].a == 56);
  616. assert(vec[0][0][0].b == 1);
  617. assert(vec[0][0][0].c == "oi");
  618. assert(vec[0][0][1].a == 78);
  619. assert(vec[0][0][1].b == 6);
  620. assert(vec[0][0][1].c == "bc");
  621. assert(vec[0][1][0].a == 89);
  622. assert(vec[0][1][0].b == 4);
  623. assert(vec[0][1][0].c == "sn");
  624. assert(vec[0][1][1].a == 42);
  625. assert(vec[0][1][1].b == 56);
  626. assert(vec[0][1][1].c == "cn");
  627. assert(vec[0][2][0].a == 23);
  628. assert(vec[0][2][0].b == 78);
  629. assert(vec[0][2][0].c == "fr");
  630. assert(vec[0][2][1].a == 445);
  631. assert(vec[0][2][1].b == 46);
  632. assert(vec[0][2][1].c == "br");
  633. assert(g == -90);
  634. }
  635. function multiDimInt(bytes memory buffer) public pure {
  636. uint16[4][2][] memory vec = abi.decode(buffer, (uint16[4][2][]));
  637. assert(vec.length == 2);
  638. assert(vec[0][0][0] == 1);
  639. assert(vec[0][0][1] == 2);
  640. assert(vec[0][0][2] == 3);
  641. assert(vec[0][0][3] == 4);
  642. assert(vec[0][1][0] == 5);
  643. assert(vec[0][1][1] == 6);
  644. assert(vec[0][1][2] == 7);
  645. assert(vec[0][1][3] == 8);
  646. assert(vec[1][0][0] == 9);
  647. assert(vec[1][0][1] == 10);
  648. assert(vec[1][0][2] == 11);
  649. assert(vec[1][0][3] == 12);
  650. assert(vec[1][1][0] == 13);
  651. assert(vec[1][1][1] == 14);
  652. assert(vec[1][1][2] == 15);
  653. assert(vec[1][1][3] == 16);
  654. }
  655. function uniqueDim(bytes memory buffer) public pure {
  656. uint16[] memory vec = abi.decode(buffer, (uint16[]));
  657. assert(vec.length == 5);
  658. assert(vec[0] == 9);
  659. assert(vec[1] == 3);
  660. assert(vec[2] == 4);
  661. assert(vec[3] == 90);
  662. assert(vec[4] == 834);
  663. }
  664. }
  665. "#,
  666. );
  667. let data_account = vm.initialize_data_account();
  668. vm.function("new")
  669. .accounts(vec![("dataAccount", data_account)])
  670. .call();
  671. let mut response: Vec<u8> = vec![0; 32];
  672. let input = Input1 {
  673. item_1: vec![[
  674. [
  675. PaddedStruct {
  676. a: 56,
  677. b: 1,
  678. c: create_response(&mut response, b"oi"),
  679. },
  680. PaddedStruct {
  681. a: 78,
  682. b: 6,
  683. c: create_response(&mut response, b"bc"),
  684. },
  685. ],
  686. [
  687. PaddedStruct {
  688. a: 89,
  689. b: 4,
  690. c: create_response(&mut response, b"sn"),
  691. },
  692. PaddedStruct {
  693. a: 42,
  694. b: 56,
  695. c: create_response(&mut response, b"cn"),
  696. },
  697. ],
  698. [
  699. PaddedStruct {
  700. a: 23,
  701. b: 78,
  702. c: create_response(&mut response, b"fr"),
  703. },
  704. PaddedStruct {
  705. a: 445,
  706. b: 46,
  707. c: create_response(&mut response, b"br"),
  708. },
  709. ],
  710. ]],
  711. item_2: -90,
  712. };
  713. let encoded = input.try_to_vec().unwrap();
  714. let _ = vm
  715. .function("multiDimStruct")
  716. .arguments(&[BorshToken::Bytes(encoded)])
  717. .call();
  718. let input = Input2 {
  719. vec: vec![
  720. [[1, 2, 3, 4], [5, 6, 7, 8]],
  721. [[9, 10, 11, 12], [13, 14, 15, 16]],
  722. ],
  723. };
  724. let encoded = input.try_to_vec().unwrap();
  725. let _ = vm
  726. .function("multiDimInt")
  727. .arguments(&[BorshToken::Bytes(encoded)])
  728. .call();
  729. let input = Input3 {
  730. vec: vec![9, 3, 4, 90, 834],
  731. };
  732. let encoded = input.try_to_vec().unwrap();
  733. let _ = vm
  734. .function("uniqueDim")
  735. .arguments(&[BorshToken::Bytes(encoded)])
  736. .call();
  737. }
  738. #[test]
  739. fn empty_arrays() {
  740. #[derive(Debug, BorshSerialize)]
  741. struct S {
  742. f1: i64,
  743. f2: String,
  744. }
  745. #[derive(Debug, BorshSerialize)]
  746. struct Input {
  747. vec_1: Vec<S>,
  748. vec_2: Vec<String>,
  749. }
  750. let mut vm = build_solidity(
  751. r#"
  752. contract Testing {
  753. struct S {
  754. int64 f1;
  755. string f2;
  756. }
  757. function testEmpty(bytes memory buffer) public pure {
  758. (S[] memory vec_1, string[] memory vec_2) = abi.decode(buffer, (S[], string[]));
  759. assert(vec_1.length == 0);
  760. assert(vec_2.length == 0);
  761. }
  762. }
  763. "#,
  764. );
  765. let data_account = vm.initialize_data_account();
  766. vm.function("new")
  767. .accounts(vec![("dataAccount", data_account)])
  768. .call();
  769. let input = Input {
  770. vec_1: vec![],
  771. vec_2: vec![],
  772. };
  773. let encoded = input.try_to_vec().unwrap();
  774. let _ = vm
  775. .function("testEmpty")
  776. .arguments(&[BorshToken::Bytes(encoded)])
  777. .call();
  778. }
  779. #[test]
  780. fn external_function() {
  781. #[derive(Debug, BorshSerialize)]
  782. struct Input {
  783. selector: [u8; 8],
  784. address: [u8; 32],
  785. }
  786. let mut vm = build_solidity(
  787. r#"
  788. contract Testing {
  789. function testExternalFunction(bytes memory buffer) public view returns (bytes8, address) {
  790. function (uint8) external returns (int8) fPtr = abi.decode(buffer, (function (uint8) external returns (int8)));
  791. return (fPtr.selector, fPtr.address);
  792. }
  793. }
  794. "#,
  795. );
  796. let data_account = vm.initialize_data_account();
  797. vm.function("new")
  798. .accounts(vec![("dataAccount", data_account)])
  799. .call();
  800. let input = Input {
  801. selector: [1, 2, 3, 4, 5, 6, 7, 8],
  802. address: [
  803. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
  804. 24, 25, 26, 27, 28, 29, 30, 31,
  805. ],
  806. };
  807. let encoded = input.try_to_vec().unwrap();
  808. let returns = vm
  809. .function("testExternalFunction")
  810. .arguments(&[BorshToken::Bytes(encoded)])
  811. .accounts(vec![("dataAccount", data_account)])
  812. .call()
  813. .unwrap()
  814. .unwrap_tuple();
  815. let selector = returns[0].clone().into_fixed_bytes().unwrap();
  816. assert_eq!(selector, input.selector);
  817. let address = returns[1].clone().into_fixed_bytes().unwrap();
  818. assert_eq!(address, input.address);
  819. }
  820. #[test]
  821. fn bytes_arrays() {
  822. #[derive(Debug, BorshSerialize)]
  823. struct Input {
  824. item_1: [[u8; 4]; 2],
  825. item_2: Vec<[u8; 5]>,
  826. }
  827. let mut vm = build_solidity(
  828. r#"
  829. contract Testing {
  830. function testByteArrays(bytes memory buffer) public view {
  831. (bytes4[2] memory arr, bytes5[] memory vec) = abi.decode(buffer, (bytes4[2], bytes5[]));
  832. assert(arr[0] == "abcd");
  833. assert(arr[1] == "efgh");
  834. assert(vec.length == 2);
  835. assert(vec[0] == "12345");
  836. assert(vec[1] == "67890");
  837. }
  838. }
  839. "#,
  840. );
  841. let data_account = vm.initialize_data_account();
  842. vm.function("new")
  843. .accounts(vec![("dataAccount", data_account)])
  844. .call();
  845. let input = Input {
  846. item_1: [b"abcd".to_owned(), b"efgh".to_owned()],
  847. item_2: vec![b"12345".to_owned(), b"67890".to_owned()],
  848. };
  849. let encoded = input.try_to_vec().unwrap();
  850. let _ = vm
  851. .function("testByteArrays")
  852. .arguments(&[BorshToken::Bytes(encoded)])
  853. .accounts(vec![("dataAccount", data_account)])
  854. .call();
  855. }
  856. #[test]
  857. #[should_panic(expected = "unexpected return 0x100000000")]
  858. fn different_types() {
  859. #[derive(Debug, BorshSerialize)]
  860. struct Input1 {
  861. a: i32,
  862. b: u64,
  863. }
  864. let mut vm = build_solidity(
  865. r#"
  866. contract Testing {
  867. function testByteArrays(bytes memory buffer) public view {
  868. (bytes4[2] memory arr, bytes5[] memory vec) = abi.decode(buffer, (bytes4[2], bytes5[]));
  869. assert(arr[0] == "abcd");
  870. assert(arr[1] == "efgh");
  871. assert(vec.length == 2);
  872. assert(vec[0] == "12345");
  873. assert(vec[1] == "67890");
  874. }
  875. }
  876. "#,
  877. );
  878. let data_account = vm.initialize_data_account();
  879. vm.function("new")
  880. .accounts(vec![("dataAccount", data_account)])
  881. .call();
  882. let input = Input1 { a: -789, b: 14234 };
  883. let encoded = input.try_to_vec().unwrap();
  884. let _ = vm
  885. .function("testByteArrays")
  886. .arguments(&[BorshToken::Bytes(encoded)])
  887. .accounts(vec![("dataAccount", data_account)])
  888. .call();
  889. }
  890. #[test]
  891. #[should_panic(expected = "unexpected return 0x100000000")]
  892. fn more_elements() {
  893. #[derive(Debug, BorshSerialize)]
  894. struct Input {
  895. vec: [i64; 4],
  896. }
  897. let mut vm = build_solidity(
  898. r#"
  899. contract Testing {
  900. function wrongNumber(bytes memory buffer) public view {
  901. int64[5] memory vec = abi.decode(buffer, (int64[5]));
  902. assert(vec[1] == 0);
  903. }
  904. }
  905. "#,
  906. );
  907. let data_account = vm.initialize_data_account();
  908. vm.function("new")
  909. .accounts(vec![("dataAccount", data_account)])
  910. .call();
  911. let input = Input { vec: [1, 4, 5, 6] };
  912. let encoded = input.try_to_vec().unwrap();
  913. let _ = vm
  914. .function("wrongNumber")
  915. .arguments(&[BorshToken::Bytes(encoded)])
  916. .accounts(vec![("dataAccount", data_account)])
  917. .call();
  918. }
  919. #[test]
  920. #[should_panic(expected = "unexpected return 0x100000000")]
  921. fn extra_element() {
  922. #[derive(Debug, BorshSerialize)]
  923. struct Input {
  924. vec: Vec<i64>,
  925. }
  926. let mut vm = build_solidity(
  927. r#"
  928. contract Testing {
  929. function extraElement(bytes memory buffer) public pure {
  930. (int64[] memory vec, int32 g) = abi.decode(buffer, (int64[], int32));
  931. assert(vec[1] == 0);
  932. assert(g == 3);
  933. }
  934. }
  935. "#,
  936. );
  937. let data_account = vm.initialize_data_account();
  938. vm.function("new")
  939. .accounts(vec![("dataAccount", data_account)])
  940. .call();
  941. let input = Input {
  942. vec: vec![-90, 89, -2341],
  943. };
  944. let encoded = input.try_to_vec().unwrap();
  945. let _ = vm
  946. .function("extraElement")
  947. .arguments(&[BorshToken::Bytes(encoded)])
  948. .call();
  949. }
  950. #[test]
  951. #[should_panic(expected = "unexpected return 0x100000000")]
  952. fn invalid_type() {
  953. #[derive(Debug, BorshSerialize)]
  954. struct Input {
  955. item: u64,
  956. }
  957. let mut vm = build_solidity(
  958. r#"
  959. contract Testing {
  960. function invalidType(bytes memory buffer) public pure {
  961. int64[] memory vec = abi.decode(buffer, (int64[]));
  962. assert(vec[1] == 0);
  963. }
  964. }
  965. "#,
  966. );
  967. let data_account = vm.initialize_data_account();
  968. vm.function("new")
  969. .accounts(vec![("dataAccount", data_account)])
  970. .call();
  971. let input = Input { item: 5 };
  972. let encoded = input.try_to_vec().unwrap();
  973. let _ = vm
  974. .function("invalidType")
  975. .arguments(&[BorshToken::Bytes(encoded)])
  976. .call();
  977. }
  978. #[test]
  979. #[should_panic(expected = "unexpected return 0x100000000")]
  980. fn longer_buffer() {
  981. #[derive(Debug, BorshSerialize)]
  982. struct Input {
  983. item_1: u64,
  984. item_2: u64,
  985. }
  986. let mut vm = build_solidity(
  987. r#"
  988. contract Testing {
  989. function testLongerBuffer(bytes memory buffer) public view {
  990. uint64 a = abi.decode(buffer, (uint64));
  991. assert(a == 4);
  992. }
  993. }
  994. "#,
  995. );
  996. let data_account = vm.initialize_data_account();
  997. vm.function("new")
  998. .accounts(vec![("dataAccount", data_account)])
  999. .call();
  1000. let input = Input {
  1001. item_1: 4,
  1002. item_2: 5,
  1003. };
  1004. let encoded = input.try_to_vec().unwrap();
  1005. let _ = vm
  1006. .function("testLongerBuffer")
  1007. .arguments(&[BorshToken::Bytes(encoded)])
  1008. .accounts(vec![("dataAccount", data_account)])
  1009. .call();
  1010. }
  1011. #[test]
  1012. #[should_panic(expected = "unexpected return 0x100000000")]
  1013. fn longer_buffer_array() {
  1014. #[derive(Debug, BorshSerialize)]
  1015. struct Input {
  1016. item_1: u64,
  1017. item_2: [u32; 4],
  1018. }
  1019. let mut vm = build_solidity(
  1020. r#"
  1021. contract Testing {
  1022. function testLongerBuffer(bytes memory buffer) public view {
  1023. (uint64 a, uint32[3] memory b) = abi.decode(buffer, (uint64, uint32[3]));
  1024. assert(a == 4);
  1025. assert(b[0] == 1);
  1026. assert(b[1] == 2);
  1027. assert(b[2] == 3);
  1028. }
  1029. } "#,
  1030. );
  1031. let data_account = vm.initialize_data_account();
  1032. vm.function("new")
  1033. .accounts(vec![("dataAccount", data_account)])
  1034. .call();
  1035. let input = Input {
  1036. item_1: 23434,
  1037. item_2: [1, 2, 3, 4],
  1038. };
  1039. let encoded = input.try_to_vec().unwrap();
  1040. let _ = vm
  1041. .function("testLongerBuffer")
  1042. .arguments(&[BorshToken::Bytes(encoded)])
  1043. .accounts(vec![("dataAccount", data_account)])
  1044. .call();
  1045. }
  1046. #[test]
  1047. fn dynamic_array_of_array() {
  1048. #[derive(Debug, BorshSerialize)]
  1049. struct Input {
  1050. vec: Vec<[i32; 2]>,
  1051. }
  1052. let mut vm = build_solidity(
  1053. r#"
  1054. contract Testing {
  1055. function testArrayAssign(bytes memory buffer) public pure {
  1056. int32[2][] memory vec = abi.decode(buffer, (int32[2][]));
  1057. assert(vec.length == 2);
  1058. assert(vec[0][0] == 0);
  1059. assert(vec[0][1] == 1);
  1060. assert(vec[1][0] == 2);
  1061. assert(vec[1][1] == -3);
  1062. }
  1063. }
  1064. "#,
  1065. );
  1066. let data_account = vm.initialize_data_account();
  1067. vm.function("new")
  1068. .accounts(vec![("dataAccount", data_account)])
  1069. .call();
  1070. let input = Input {
  1071. vec: vec![[0, 1], [2, -3]],
  1072. };
  1073. let encoded = input.try_to_vec().unwrap();
  1074. let _ = vm
  1075. .function("testArrayAssign")
  1076. .arguments(&[BorshToken::Bytes(encoded)])
  1077. .call();
  1078. }
  1079. #[test]
  1080. fn test_struct_validation() {
  1081. #[derive(Debug, BorshSerialize)]
  1082. struct MyStruct {
  1083. b: [u8; 32],
  1084. c: i8,
  1085. d: String,
  1086. }
  1087. #[derive(Debug, BorshSerialize)]
  1088. struct Input {
  1089. b: u128,
  1090. m_str: MyStruct,
  1091. }
  1092. let mut vm = build_solidity(
  1093. r#"
  1094. contract Testing {
  1095. struct myStruct {
  1096. bytes32 b;
  1097. int8 c;
  1098. string d;
  1099. }
  1100. function test(bytes memory buffer) public pure {
  1101. (uint128 b, myStruct memory m_str) = abi.decode(buffer, (uint128, myStruct));
  1102. assert(m_str.b == "struct");
  1103. assert(m_str.c == 1);
  1104. assert(m_str.d == "string");
  1105. assert(b == 3);
  1106. }
  1107. }
  1108. "#,
  1109. );
  1110. let data_account = vm.initialize_data_account();
  1111. vm.function("new")
  1112. .accounts(vec![("dataAccount", data_account)])
  1113. .call();
  1114. let mut bytes_string = b"struct".to_vec();
  1115. bytes_string.append(&mut vec![0; 26]);
  1116. let input = Input {
  1117. b: 3,
  1118. m_str: MyStruct {
  1119. b: <[u8; 32]>::try_from(bytes_string).unwrap(),
  1120. c: 1,
  1121. d: "string".to_string(),
  1122. },
  1123. };
  1124. let encoded = input.try_to_vec().unwrap();
  1125. let _ = vm
  1126. .function("test")
  1127. .arguments(&[BorshToken::Bytes(encoded)])
  1128. .call();
  1129. }
  1130. #[test]
  1131. #[should_panic(expected = "unexpected return 0x100000000")]
  1132. fn test_struct_validation_invalid() {
  1133. #[derive(Debug, BorshSerialize)]
  1134. struct MyStruct {
  1135. b: [u8; 32],
  1136. c: i8,
  1137. d: String,
  1138. }
  1139. #[derive(Debug, BorshSerialize)]
  1140. struct Input {
  1141. m_str: MyStruct,
  1142. }
  1143. let mut vm = build_solidity(
  1144. r#"
  1145. contract Testing {
  1146. struct myStruct {
  1147. bytes32 b;
  1148. int8 c;
  1149. string d;
  1150. }
  1151. function test(bytes memory buffer) public pure {
  1152. (uint128 b, myStruct memory m_str) = abi.decode(buffer, (uint128, myStruct));
  1153. assert(m_str.b == "struct");
  1154. assert(m_str.c == 1);
  1155. assert(m_str.d == "string");
  1156. assert(b == 3);
  1157. }
  1158. }
  1159. "#,
  1160. );
  1161. let data_account = vm.initialize_data_account();
  1162. vm.function("new")
  1163. .accounts(vec![("dataAccount", data_account)])
  1164. .call();
  1165. let mut bytes_string = b"struct".to_vec();
  1166. bytes_string.append(&mut vec![0; 26]);
  1167. let input = Input {
  1168. m_str: MyStruct {
  1169. b: <[u8; 32]>::try_from(bytes_string).unwrap(),
  1170. c: 1,
  1171. d: "string".to_string(),
  1172. },
  1173. };
  1174. let encoded = input.try_to_vec().unwrap();
  1175. let _ = vm
  1176. .function("test")
  1177. .arguments(&[BorshToken::Bytes(encoded)])
  1178. .call();
  1179. }
  1180. #[test]
  1181. fn string_fixed_array() {
  1182. let mut vm = build_solidity(
  1183. r#"
  1184. contract test {
  1185. function testing(bytes memory data) public pure {
  1186. string[4] arr = abi.decode(data, (string[4]));
  1187. assert(arr[0] == "a");
  1188. assert(arr[1] == "b");
  1189. assert(arr[2] == "c");
  1190. assert(arr[3] == "d");
  1191. }
  1192. }
  1193. "#,
  1194. );
  1195. let data_account = vm.initialize_data_account();
  1196. vm.function("new")
  1197. .accounts(vec![("dataAccount", data_account)])
  1198. .call();
  1199. #[derive(Debug, BorshSerialize)]
  1200. struct Input {
  1201. a: [String; 4],
  1202. }
  1203. let input = Input {
  1204. a: [
  1205. "a".to_string(),
  1206. "b".to_string(),
  1207. "c".to_string(),
  1208. "d".to_string(),
  1209. ],
  1210. };
  1211. let encoded = input.try_to_vec().unwrap();
  1212. let _ = vm
  1213. .function("testing")
  1214. .arguments(&[BorshToken::Bytes(encoded)])
  1215. .call();
  1216. }
  1217. #[test]
  1218. fn double_dynamic_array() {
  1219. let mut vm = build_solidity(
  1220. r#"
  1221. contract Testing {
  1222. function testThis(bytes memory bb) public pure {
  1223. (uint32 a, uint16[][] memory vec, int64 b) = abi.decode(bb, (uint32, uint16[][], int64));
  1224. assert(a == 99);
  1225. assert(vec[0][0] == 99);
  1226. assert(vec[0][1] == 20);
  1227. assert(vec[1][0] == 15);
  1228. assert(vec[1][1] == 88);
  1229. assert(b == -755);
  1230. }
  1231. }
  1232. "#,
  1233. );
  1234. let data_account = vm.initialize_data_account();
  1235. vm.function("new")
  1236. .accounts(vec![("dataAccount", data_account)])
  1237. .call();
  1238. #[derive(Debug, BorshSerialize)]
  1239. struct Input {
  1240. item_1: u32,
  1241. item_2: Vec<Vec<u16>>,
  1242. item_3: i64,
  1243. }
  1244. let input = Input {
  1245. item_1: 99,
  1246. item_2: vec![vec![99, 20], vec![15, 88]],
  1247. item_3: -755,
  1248. };
  1249. let encoded = input.try_to_vec().unwrap();
  1250. let _ = vm
  1251. .function("testThis")
  1252. .arguments(&[BorshToken::Bytes(encoded)])
  1253. .call();
  1254. }