fundraiser.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import * as anchor from '@coral-xyz/anchor';
  2. import type { Program } from '@coral-xyz/anchor';
  3. import type NodeWallet from '@coral-xyz/anchor/dist/cjs/nodewallet';
  4. import {
  5. ASSOCIATED_TOKEN_PROGRAM_ID,
  6. TOKEN_PROGRAM_ID,
  7. createMint,
  8. getAssociatedTokenAddressSync,
  9. getOrCreateAssociatedTokenAccount,
  10. mintTo,
  11. } from '@solana/spl-token';
  12. import type { Fundraiser } from '../target/types/fundraiser';
  13. describe('fundraiser', () => {
  14. // Configure the client to use the local cluster.
  15. const provider = anchor.AnchorProvider.env();
  16. anchor.setProvider(provider);
  17. const program = anchor.workspace.Fundraiser as Program<Fundraiser>;
  18. const maker = anchor.web3.Keypair.generate();
  19. let mint: anchor.web3.PublicKey;
  20. let contributorATA: anchor.web3.PublicKey;
  21. let makerATA: anchor.web3.PublicKey;
  22. const wallet = provider.wallet as NodeWallet;
  23. const fundraiser = anchor.web3.PublicKey.findProgramAddressSync([Buffer.from('fundraiser'), maker.publicKey.toBuffer()], program.programId)[0];
  24. const contributor = anchor.web3.PublicKey.findProgramAddressSync(
  25. [Buffer.from('contributor'), fundraiser.toBuffer(), provider.publicKey.toBuffer()],
  26. program.programId,
  27. )[0];
  28. const confirm = async (signature: string): Promise<string> => {
  29. const block = await provider.connection.getLatestBlockhash();
  30. await provider.connection.confirmTransaction({
  31. signature,
  32. ...block,
  33. });
  34. return signature;
  35. };
  36. it('Test Preparation', async () => {
  37. const airdrop = await provider.connection.requestAirdrop(maker.publicKey, 1 * anchor.web3.LAMPORTS_PER_SOL).then(confirm);
  38. console.log('\nAirdropped 1 SOL to maker', airdrop);
  39. mint = await createMint(provider.connection, wallet.payer, provider.publicKey, provider.publicKey, 6);
  40. console.log('Mint created', mint.toBase58());
  41. contributorATA = (await getOrCreateAssociatedTokenAccount(provider.connection, wallet.payer, mint, wallet.publicKey)).address;
  42. makerATA = (await getOrCreateAssociatedTokenAccount(provider.connection, wallet.payer, mint, maker.publicKey)).address;
  43. const mintTx = await mintTo(provider.connection, wallet.payer, mint, contributorATA, provider.publicKey, 1_000_000_0);
  44. console.log('Minted 10 tokens to contributor', mintTx);
  45. });
  46. it('Initialize Fundaraiser', async () => {
  47. const vault = getAssociatedTokenAddressSync(mint, fundraiser, true);
  48. const tx = await program.methods
  49. .initialize(new anchor.BN(30000000), 0)
  50. .accountsPartial({
  51. maker: maker.publicKey,
  52. fundraiser,
  53. mintToRaise: mint,
  54. vault,
  55. systemProgram: anchor.web3.SystemProgram.programId,
  56. tokenProgram: TOKEN_PROGRAM_ID,
  57. associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
  58. })
  59. .signers([maker])
  60. .rpc()
  61. .then(confirm);
  62. console.log('\nInitialized fundraiser Account');
  63. console.log('Your transaction signature', tx);
  64. });
  65. it('Contribute to Fundraiser', async () => {
  66. const vault = getAssociatedTokenAddressSync(mint, fundraiser, true);
  67. const tx = await program.methods
  68. .contribute(new anchor.BN(1000000))
  69. .accountsPartial({
  70. contributor: provider.publicKey,
  71. fundraiser,
  72. contributorAccount: contributor,
  73. contributorAta: contributorATA,
  74. vault,
  75. tokenProgram: TOKEN_PROGRAM_ID,
  76. })
  77. .rpc()
  78. .then(confirm);
  79. console.log('\nContributed to fundraiser', tx);
  80. console.log('Your transaction signature', tx);
  81. console.log('Vault balance', (await provider.connection.getTokenAccountBalance(vault)).value.amount);
  82. const contributorAccount = await program.account.contributor.fetch(contributor);
  83. console.log('Contributor balance', contributorAccount.amount.toString());
  84. });
  85. it('Contribute to Fundraiser', async () => {
  86. const vault = getAssociatedTokenAddressSync(mint, fundraiser, true);
  87. const tx = await program.methods
  88. .contribute(new anchor.BN(1000000))
  89. .accountsPartial({
  90. contributor: provider.publicKey,
  91. fundraiser,
  92. contributorAccount: contributor,
  93. contributorAta: contributorATA,
  94. vault,
  95. tokenProgram: TOKEN_PROGRAM_ID,
  96. })
  97. .rpc()
  98. .then(confirm);
  99. console.log('\nContributed to fundraiser', tx);
  100. console.log('Your transaction signature', tx);
  101. console.log('Vault balance', (await provider.connection.getTokenAccountBalance(vault)).value.amount);
  102. const contributorAccount = await program.account.contributor.fetch(contributor);
  103. console.log('Contributor balance', contributorAccount.amount.toString());
  104. });
  105. it('Contribute to Fundraiser - Robustness Test', async () => {
  106. try {
  107. const vault = getAssociatedTokenAddressSync(mint, fundraiser, true);
  108. const tx = await program.methods
  109. .contribute(new anchor.BN(2000000))
  110. .accountsPartial({
  111. contributor: provider.publicKey,
  112. fundraiser,
  113. contributorAccount: contributor,
  114. contributorAta: contributorATA,
  115. vault,
  116. tokenProgram: TOKEN_PROGRAM_ID,
  117. })
  118. .rpc()
  119. .then(confirm);
  120. console.log('\nContributed to fundraiser', tx);
  121. console.log('Your transaction signature', tx);
  122. console.log('Vault balance', (await provider.connection.getTokenAccountBalance(vault)).value.amount);
  123. } catch (error) {
  124. console.log('\nError contributing to fundraiser');
  125. console.log(error.msg);
  126. }
  127. });
  128. it('Check contributions - Robustness Test', async () => {
  129. try {
  130. const vault = getAssociatedTokenAddressSync(mint, fundraiser, true);
  131. const tx = await program.methods
  132. .checkContributions()
  133. .accountsPartial({
  134. maker: maker.publicKey,
  135. mintToRaise: mint,
  136. fundraiser,
  137. makerAta: makerATA,
  138. vault,
  139. tokenProgram: TOKEN_PROGRAM_ID,
  140. })
  141. .signers([maker])
  142. .rpc()
  143. .then(confirm);
  144. console.log('\nChecked contributions');
  145. console.log('Your transaction signature', tx);
  146. console.log('Vault balance', (await provider.connection.getTokenAccountBalance(vault)).value.amount);
  147. } catch (error) {
  148. console.log('\nError checking contributions');
  149. console.log(error.msg);
  150. }
  151. });
  152. it('Refund Contributions', async () => {
  153. const vault = getAssociatedTokenAddressSync(mint, fundraiser, true);
  154. const contributorAccount = await program.account.contributor.fetch(contributor);
  155. console.log('\nContributor balance', contributorAccount.amount.toString());
  156. const tx = await program.methods
  157. .refund()
  158. .accountsPartial({
  159. contributor: provider.publicKey,
  160. maker: maker.publicKey,
  161. mintToRaise: mint,
  162. fundraiser,
  163. contributorAccount: contributor,
  164. contributorAta: contributorATA,
  165. vault,
  166. tokenProgram: TOKEN_PROGRAM_ID,
  167. systemProgram: anchor.web3.SystemProgram.programId,
  168. })
  169. .rpc()
  170. .then(confirm);
  171. console.log('\nRefunded contributions', tx);
  172. console.log('Your transaction signature', tx);
  173. console.log('Vault balance', (await provider.connection.getTokenAccountBalance(vault)).value.amount);
  174. });
  175. });