abi_decode.rs 36 KB

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