metas.rs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::{
  3. account_new, build_solidity, build_solidity_with_cache, AccountMeta, AccountState, BorshToken,
  4. Pubkey,
  5. };
  6. use borsh::BorshSerialize;
  7. use num_bigint::BigInt;
  8. use solang::file_resolver::FileResolver;
  9. #[test]
  10. fn use_authority() {
  11. let mut vm = build_solidity(include_str!("../../docs/examples/solana/use_authority.sol"));
  12. let authority = account_new();
  13. vm.account_data.insert(
  14. authority,
  15. AccountState {
  16. data: vec![],
  17. owner: Some([0u8; 32]),
  18. lamports: 0,
  19. },
  20. );
  21. let data_account = vm.initialize_data_account();
  22. vm.function("new")
  23. .arguments(&[BorshToken::Address(authority)])
  24. .accounts(vec![("dataAccount", data_account)])
  25. .call();
  26. let res = vm
  27. .function("inc")
  28. .accounts(vec![("dataAccount", data_account)])
  29. .must_fail()
  30. .unwrap();
  31. assert_ne!(res, 0);
  32. let res = vm
  33. .function("get")
  34. .accounts(vec![("dataAccount", data_account)])
  35. .call()
  36. .unwrap();
  37. assert_eq!(
  38. res,
  39. BorshToken::Uint {
  40. width: 64,
  41. value: 0.into()
  42. }
  43. );
  44. vm.function("inc")
  45. .accounts(vec![("dataAccount", data_account)])
  46. .remaining_accounts(&[AccountMeta {
  47. pubkey: Pubkey(authority),
  48. is_signer: true,
  49. is_writable: false,
  50. }])
  51. .call();
  52. let res = vm
  53. .function("get")
  54. .accounts(vec![("dataAccount", data_account)])
  55. .call()
  56. .unwrap();
  57. assert_eq!(
  58. res,
  59. BorshToken::Uint {
  60. width: 64,
  61. value: 1.into()
  62. }
  63. );
  64. }
  65. #[test]
  66. fn token_account() {
  67. let mut cache = FileResolver::default();
  68. cache.set_file_contents(
  69. "spl_token.sol",
  70. include_str!("../../solana-library/spl_token.sol").to_string(),
  71. );
  72. let src = r#"
  73. import './spl_token.sol';
  74. contract Foo {
  75. function token_account(address add) public returns (SplToken.TokenAccountData) {
  76. return SplToken.get_token_account_data(add);
  77. }
  78. }
  79. "#;
  80. cache.set_file_contents("test.sol", src.to_string());
  81. let mut vm = build_solidity_with_cache(cache);
  82. #[derive(BorshSerialize)]
  83. struct TokenAccount {
  84. mint_account: [u8; 32],
  85. owner: [u8; 32],
  86. balance: u64,
  87. delegate_present: u32,
  88. delegate: [u8; 32],
  89. state: u8,
  90. is_native_present: u32,
  91. is_native: u64,
  92. delegated_amount: u64,
  93. close_authority_present: u32,
  94. close_authority: [u8; 32],
  95. }
  96. let mut data = TokenAccount {
  97. mint_account: account_new(),
  98. owner: account_new(),
  99. balance: 234,
  100. delegate_present: 0,
  101. delegate: account_new(),
  102. state: 1,
  103. is_native_present: 0,
  104. is_native: 234,
  105. delegated_amount: 1346,
  106. close_authority_present: 0,
  107. close_authority: account_new(),
  108. };
  109. let encoded = data.try_to_vec().unwrap();
  110. let account = account_new();
  111. vm.account_data.insert(
  112. account,
  113. AccountState {
  114. owner: None,
  115. lamports: 0,
  116. data: encoded,
  117. },
  118. );
  119. let data_account = vm.initialize_data_account();
  120. vm.function("new")
  121. .accounts(vec![("dataAccount", data_account)])
  122. .call();
  123. let res = vm
  124. .function("token_account")
  125. .arguments(&[BorshToken::Address(account)])
  126. .accounts(vec![("dataAccount", data_account)])
  127. .remaining_accounts(&[AccountMeta {
  128. pubkey: Pubkey(account),
  129. is_signer: false,
  130. is_writable: false,
  131. }])
  132. .call()
  133. .unwrap()
  134. .unwrap_tuple();
  135. assert_eq!(
  136. res,
  137. vec![
  138. BorshToken::Address(data.mint_account),
  139. BorshToken::Address(data.owner),
  140. BorshToken::Uint {
  141. width: 64,
  142. value: BigInt::from(data.balance)
  143. },
  144. BorshToken::Bool(data.delegate_present > 0),
  145. BorshToken::Address(data.delegate),
  146. BorshToken::Uint {
  147. width: 8,
  148. value: BigInt::from(data.state)
  149. },
  150. BorshToken::Bool(data.is_native_present > 0),
  151. BorshToken::Uint {
  152. width: 64,
  153. value: BigInt::from(data.is_native)
  154. },
  155. BorshToken::Uint {
  156. width: 64,
  157. value: BigInt::from(data.delegated_amount)
  158. },
  159. BorshToken::Bool(data.close_authority_present > 0),
  160. BorshToken::Address(data.close_authority)
  161. ]
  162. );
  163. data.delegate_present = 1;
  164. data.is_native_present = 1;
  165. data.close_authority_present = 1;
  166. let encoded = data.try_to_vec().unwrap();
  167. vm.account_data.get_mut(&account).unwrap().data = encoded;
  168. let res = vm
  169. .function("token_account")
  170. .arguments(&[BorshToken::Address(account)])
  171. .accounts(vec![("dataAccount", data_account)])
  172. .remaining_accounts(&[AccountMeta {
  173. pubkey: Pubkey(account),
  174. is_signer: false,
  175. is_writable: false,
  176. }])
  177. .call()
  178. .unwrap()
  179. .unwrap_tuple();
  180. assert_eq!(
  181. res,
  182. vec![
  183. BorshToken::Address(data.mint_account),
  184. BorshToken::Address(data.owner),
  185. BorshToken::Uint {
  186. width: 64,
  187. value: BigInt::from(data.balance)
  188. },
  189. BorshToken::Bool(data.delegate_present > 0),
  190. BorshToken::Address(data.delegate),
  191. BorshToken::Uint {
  192. width: 8,
  193. value: BigInt::from(data.state)
  194. },
  195. BorshToken::Bool(data.is_native_present > 0),
  196. BorshToken::Uint {
  197. width: 64,
  198. value: BigInt::from(data.is_native)
  199. },
  200. BorshToken::Uint {
  201. width: 64,
  202. value: BigInt::from(data.delegated_amount)
  203. },
  204. BorshToken::Bool(data.close_authority_present > 0),
  205. BorshToken::Address(data.close_authority)
  206. ]
  207. );
  208. }
  209. #[test]
  210. fn mint_account() {
  211. let mut cache = FileResolver::default();
  212. cache.set_file_contents(
  213. "spl_token.sol",
  214. include_str!("../../solana-library/spl_token.sol").to_string(),
  215. );
  216. let src = r#"
  217. import './spl_token.sol';
  218. contract Foo {
  219. function mint_account(address add) public returns (SplToken.MintAccountData) {
  220. return SplToken.get_mint_account_data(add);
  221. }
  222. }
  223. "#;
  224. cache.set_file_contents("test.sol", src.to_string());
  225. let mut vm = build_solidity_with_cache(cache);
  226. #[derive(BorshSerialize)]
  227. struct MintAccountData {
  228. authority_present: u32,
  229. mint_authority: [u8; 32],
  230. supply: u64,
  231. decimals: u8,
  232. is_initialized: bool,
  233. freeze_authority_present: u32,
  234. freeze_authority: [u8; 32],
  235. }
  236. let mut data = MintAccountData {
  237. authority_present: 0,
  238. mint_authority: account_new(),
  239. supply: 450,
  240. decimals: 4,
  241. is_initialized: false,
  242. freeze_authority_present: 0,
  243. freeze_authority: account_new(),
  244. };
  245. let encoded = data.try_to_vec().unwrap();
  246. let account = account_new();
  247. vm.account_data.insert(
  248. account,
  249. AccountState {
  250. owner: None,
  251. lamports: 0,
  252. data: encoded,
  253. },
  254. );
  255. let data_account = vm.initialize_data_account();
  256. vm.function("new")
  257. .accounts(vec![("dataAccount", data_account)])
  258. .call();
  259. let res = vm
  260. .function("mint_account")
  261. .accounts(vec![("dataAccount", data_account)])
  262. .arguments(&[BorshToken::Address(account)])
  263. .remaining_accounts(&[AccountMeta {
  264. pubkey: Pubkey(account),
  265. is_writable: false,
  266. is_signer: false,
  267. }])
  268. .call()
  269. .unwrap()
  270. .unwrap_tuple();
  271. assert_eq!(
  272. res,
  273. vec![
  274. BorshToken::Bool(data.authority_present > 0),
  275. BorshToken::Address(data.mint_authority),
  276. BorshToken::Uint {
  277. width: 64,
  278. value: BigInt::from(data.supply)
  279. },
  280. BorshToken::Uint {
  281. width: 8,
  282. value: BigInt::from(data.decimals)
  283. },
  284. BorshToken::Bool(data.is_initialized),
  285. BorshToken::Bool(data.freeze_authority_present > 0),
  286. BorshToken::Address(data.freeze_authority)
  287. ]
  288. );
  289. data.authority_present = 1;
  290. data.is_initialized = true;
  291. data.freeze_authority_present = 1;
  292. let encoded = data.try_to_vec().unwrap();
  293. vm.account_data.get_mut(&account).unwrap().data = encoded;
  294. let res = vm
  295. .function("mint_account")
  296. .accounts(vec![("dataAccount", data_account)])
  297. .arguments(&[BorshToken::Address(account)])
  298. .remaining_accounts(&[AccountMeta {
  299. pubkey: Pubkey(account),
  300. is_writable: false,
  301. is_signer: false,
  302. }])
  303. .call()
  304. .unwrap()
  305. .unwrap_tuple();
  306. assert_eq!(
  307. res,
  308. vec![
  309. BorshToken::Bool(data.authority_present > 0),
  310. BorshToken::Address(data.mint_authority),
  311. BorshToken::Uint {
  312. width: 64,
  313. value: BigInt::from(data.supply)
  314. },
  315. BorshToken::Uint {
  316. width: 8,
  317. value: BigInt::from(data.decimals)
  318. },
  319. BorshToken::Bool(data.is_initialized),
  320. BorshToken::Bool(data.freeze_authority_present > 0),
  321. BorshToken::Address(data.freeze_authority)
  322. ]
  323. );
  324. }