metas.rs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  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. .remaining_accounts(&[AccountMeta {
  127. pubkey: Pubkey(account),
  128. is_signer: false,
  129. is_writable: false,
  130. }])
  131. .call()
  132. .unwrap()
  133. .unwrap_tuple();
  134. assert_eq!(
  135. res,
  136. vec![
  137. BorshToken::Address(data.mint_account),
  138. BorshToken::Address(data.owner),
  139. BorshToken::Uint {
  140. width: 64,
  141. value: BigInt::from(data.balance)
  142. },
  143. BorshToken::Bool(data.delegate_present > 0),
  144. BorshToken::Address(data.delegate),
  145. BorshToken::Uint {
  146. width: 8,
  147. value: BigInt::from(data.state)
  148. },
  149. BorshToken::Bool(data.is_native_present > 0),
  150. BorshToken::Uint {
  151. width: 64,
  152. value: BigInt::from(data.is_native)
  153. },
  154. BorshToken::Uint {
  155. width: 64,
  156. value: BigInt::from(data.delegated_amount)
  157. },
  158. BorshToken::Bool(data.close_authority_present > 0),
  159. BorshToken::Address(data.close_authority)
  160. ]
  161. );
  162. data.delegate_present = 1;
  163. data.is_native_present = 1;
  164. data.close_authority_present = 1;
  165. let encoded = data.try_to_vec().unwrap();
  166. vm.account_data.get_mut(&account).unwrap().data = encoded;
  167. let res = vm
  168. .function("token_account")
  169. .arguments(&[BorshToken::Address(account)])
  170. .remaining_accounts(&[AccountMeta {
  171. pubkey: Pubkey(account),
  172. is_signer: false,
  173. is_writable: false,
  174. }])
  175. .call()
  176. .unwrap()
  177. .unwrap_tuple();
  178. assert_eq!(
  179. res,
  180. vec![
  181. BorshToken::Address(data.mint_account),
  182. BorshToken::Address(data.owner),
  183. BorshToken::Uint {
  184. width: 64,
  185. value: BigInt::from(data.balance)
  186. },
  187. BorshToken::Bool(data.delegate_present > 0),
  188. BorshToken::Address(data.delegate),
  189. BorshToken::Uint {
  190. width: 8,
  191. value: BigInt::from(data.state)
  192. },
  193. BorshToken::Bool(data.is_native_present > 0),
  194. BorshToken::Uint {
  195. width: 64,
  196. value: BigInt::from(data.is_native)
  197. },
  198. BorshToken::Uint {
  199. width: 64,
  200. value: BigInt::from(data.delegated_amount)
  201. },
  202. BorshToken::Bool(data.close_authority_present > 0),
  203. BorshToken::Address(data.close_authority)
  204. ]
  205. );
  206. }
  207. #[test]
  208. fn mint_account() {
  209. let mut cache = FileResolver::default();
  210. cache.set_file_contents(
  211. "spl_token.sol",
  212. include_str!("../../solana-library/spl_token.sol").to_string(),
  213. );
  214. let src = r#"
  215. import './spl_token.sol';
  216. contract Foo {
  217. function mint_account(address add) public returns (SplToken.MintAccountData) {
  218. return SplToken.get_mint_account_data(add);
  219. }
  220. }
  221. "#;
  222. cache.set_file_contents("test.sol", src.to_string());
  223. let mut vm = build_solidity_with_cache(cache);
  224. #[derive(BorshSerialize)]
  225. struct MintAccountData {
  226. authority_present: u32,
  227. mint_authority: [u8; 32],
  228. supply: u64,
  229. decimals: u8,
  230. is_initialized: bool,
  231. freeze_authority_present: u32,
  232. freeze_authority: [u8; 32],
  233. }
  234. let mut data = MintAccountData {
  235. authority_present: 0,
  236. mint_authority: account_new(),
  237. supply: 450,
  238. decimals: 4,
  239. is_initialized: false,
  240. freeze_authority_present: 0,
  241. freeze_authority: account_new(),
  242. };
  243. let encoded = data.try_to_vec().unwrap();
  244. let account = account_new();
  245. vm.account_data.insert(
  246. account,
  247. AccountState {
  248. owner: None,
  249. lamports: 0,
  250. data: encoded,
  251. },
  252. );
  253. let data_account = vm.initialize_data_account();
  254. vm.function("new")
  255. .accounts(vec![("dataAccount", data_account)])
  256. .call();
  257. let res = vm
  258. .function("mint_account")
  259. .arguments(&[BorshToken::Address(account)])
  260. .remaining_accounts(&[AccountMeta {
  261. pubkey: Pubkey(account),
  262. is_writable: false,
  263. is_signer: false,
  264. }])
  265. .call()
  266. .unwrap()
  267. .unwrap_tuple();
  268. assert_eq!(
  269. res,
  270. vec![
  271. BorshToken::Bool(data.authority_present > 0),
  272. BorshToken::Address(data.mint_authority),
  273. BorshToken::Uint {
  274. width: 64,
  275. value: BigInt::from(data.supply)
  276. },
  277. BorshToken::Uint {
  278. width: 8,
  279. value: BigInt::from(data.decimals)
  280. },
  281. BorshToken::Bool(data.is_initialized),
  282. BorshToken::Bool(data.freeze_authority_present > 0),
  283. BorshToken::Address(data.freeze_authority)
  284. ]
  285. );
  286. data.authority_present = 1;
  287. data.is_initialized = true;
  288. data.freeze_authority_present = 1;
  289. let encoded = data.try_to_vec().unwrap();
  290. vm.account_data.get_mut(&account).unwrap().data = encoded;
  291. let res = vm
  292. .function("mint_account")
  293. .arguments(&[BorshToken::Address(account)])
  294. .remaining_accounts(&[AccountMeta {
  295. pubkey: Pubkey(account),
  296. is_writable: false,
  297. is_signer: false,
  298. }])
  299. .call()
  300. .unwrap()
  301. .unwrap_tuple();
  302. assert_eq!(
  303. res,
  304. vec![
  305. BorshToken::Bool(data.authority_present > 0),
  306. BorshToken::Address(data.mint_authority),
  307. BorshToken::Uint {
  308. width: 64,
  309. value: BigInt::from(data.supply)
  310. },
  311. BorshToken::Uint {
  312. width: 8,
  313. value: BigInt::from(data.decimals)
  314. },
  315. BorshToken::Bool(data.is_initialized),
  316. BorshToken::Bool(data.freeze_authority_present > 0),
  317. BorshToken::Address(data.freeze_authority)
  318. ]
  319. );
  320. }