From 627d572774880bcf90ca80ba67b1f55b6cf782b8 Mon Sep 17 00:00:00 2001 From: Armani Ferrante Date: Fri, 15 Oct 2021 13:22:05 -0500 Subject: [PATCH] Basic test setup --- .travis.yml | 26 +++ Anchor.toml | 2 +- Cargo.lock | 79 ++++++--- package.json | 7 +- programs/governance-registry/Cargo.toml | 9 +- programs/governance-registry/src/lib.rs | 115 ++++++++----- tests/governance-registry.ts | 217 +++++++++++++++++------- yarn.lock | 62 ++++++- 8 files changed, 383 insertions(+), 134 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..cc34efa --- /dev/null +++ b/.travis.yml @@ -0,0 +1,26 @@ +dist: bionic +language: rust +rust: + - stable +env: + global: + - NODE_VERSION="v14.7.0" + - SOLANA_VERSION="v1.8.0" + +_defaults: &defaults + before_install: + - nvm install $NODE_VERSION + - sudo apt-get install -y pkg-config build-essential libudev-dev + - sh -c "$(curl -sSfL https://release.solana.com/${SOLANA_VERSION}/install)" + - export PATH="/home/travis/.local/share/solana/install/active_release/bin:$PATH" + - export NODE_PATH="/home/travis/.nvm/versions/node/${NODE_VERSION}/lib/node_modules/:${NODE_PATH}" + - yes | solana-keygen new + - cargo install --git https://github.com/project-serum/anchor anchor-cli --locked + +jobs: + include: + - <<: *defaults + name: Runs the tests + script: + - yarn + - yarn test diff --git a/Anchor.toml b/Anchor.toml index 0677b69..e2bee0e 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -6,4 +6,4 @@ cluster = "localnet" wallet = "~/.config/solana/id.json" [scripts] -test = "ts-mocha -p ./tsconfig.json -t 1000000 tests/*.ts" +test = "npx ts-mocha -p ./tsconfig.json -t 1000000 tests/*.ts" diff --git a/Cargo.lock b/Cargo.lock index 88c8dad..f554804 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,7 +26,7 @@ checksum = "6b2d54853319fd101b8dd81de382bcbf3e03410a64d8928bbee85a3e7dcde483" [[package]] name = "anchor-attribute-access-control" version = "0.17.0" -source = "git+https://github.com/project-serum/anchor#d9c643c499121108f9c833571fff5b165a9a0a1b" +source = "git+https://github.com/project-serum/anchor?branch=armani/solana#5925ed85289ddb43eb1266417f72b7f5433afac3" dependencies = [ "anchor-syn", "anyhow", @@ -39,7 +39,7 @@ dependencies = [ [[package]] name = "anchor-attribute-account" version = "0.17.0" -source = "git+https://github.com/project-serum/anchor#d9c643c499121108f9c833571fff5b165a9a0a1b" +source = "git+https://github.com/project-serum/anchor?branch=armani/solana#5925ed85289ddb43eb1266417f72b7f5433afac3" dependencies = [ "anchor-syn", "anyhow", @@ -53,7 +53,7 @@ dependencies = [ [[package]] name = "anchor-attribute-error" version = "0.17.0" -source = "git+https://github.com/project-serum/anchor#d9c643c499121108f9c833571fff5b165a9a0a1b" +source = "git+https://github.com/project-serum/anchor?branch=armani/solana#5925ed85289ddb43eb1266417f72b7f5433afac3" dependencies = [ "anchor-syn", "proc-macro2", @@ -64,7 +64,7 @@ dependencies = [ [[package]] name = "anchor-attribute-event" version = "0.17.0" -source = "git+https://github.com/project-serum/anchor#d9c643c499121108f9c833571fff5b165a9a0a1b" +source = "git+https://github.com/project-serum/anchor?branch=armani/solana#5925ed85289ddb43eb1266417f72b7f5433afac3" dependencies = [ "anchor-syn", "anyhow", @@ -76,7 +76,7 @@ dependencies = [ [[package]] name = "anchor-attribute-interface" version = "0.17.0" -source = "git+https://github.com/project-serum/anchor#d9c643c499121108f9c833571fff5b165a9a0a1b" +source = "git+https://github.com/project-serum/anchor?branch=armani/solana#5925ed85289ddb43eb1266417f72b7f5433afac3" dependencies = [ "anchor-syn", "anyhow", @@ -89,7 +89,7 @@ dependencies = [ [[package]] name = "anchor-attribute-program" version = "0.17.0" -source = "git+https://github.com/project-serum/anchor#d9c643c499121108f9c833571fff5b165a9a0a1b" +source = "git+https://github.com/project-serum/anchor?branch=armani/solana#5925ed85289ddb43eb1266417f72b7f5433afac3" dependencies = [ "anchor-syn", "anyhow", @@ -101,7 +101,7 @@ dependencies = [ [[package]] name = "anchor-attribute-state" version = "0.17.0" -source = "git+https://github.com/project-serum/anchor#d9c643c499121108f9c833571fff5b165a9a0a1b" +source = "git+https://github.com/project-serum/anchor?branch=armani/solana#5925ed85289ddb43eb1266417f72b7f5433afac3" dependencies = [ "anchor-syn", "anyhow", @@ -113,7 +113,7 @@ dependencies = [ [[package]] name = "anchor-derive-accounts" version = "0.17.0" -source = "git+https://github.com/project-serum/anchor#d9c643c499121108f9c833571fff5b165a9a0a1b" +source = "git+https://github.com/project-serum/anchor?branch=armani/solana#5925ed85289ddb43eb1266417f72b7f5433afac3" dependencies = [ "anchor-syn", "anyhow", @@ -125,7 +125,7 @@ dependencies = [ [[package]] name = "anchor-lang" version = "0.17.0" -source = "git+https://github.com/project-serum/anchor#d9c643c499121108f9c833571fff5b165a9a0a1b" +source = "git+https://github.com/project-serum/anchor?branch=armani/solana#5925ed85289ddb43eb1266417f72b7f5433afac3" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -145,20 +145,20 @@ dependencies = [ [[package]] name = "anchor-spl" version = "0.17.0" -source = "git+https://github.com/project-serum/anchor#d9c643c499121108f9c833571fff5b165a9a0a1b" +source = "git+https://github.com/project-serum/anchor?branch=armani/solana#5925ed85289ddb43eb1266417f72b7f5433afac3" dependencies = [ "anchor-lang", "lazy_static", "serum_dex", "solana-program", "spl-associated-token-account", - "spl-token", + "spl-token 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "anchor-syn" version = "0.17.0" -source = "git+https://github.com/project-serum/anchor#d9c643c499121108f9c833571fff5b165a9a0a1b" +source = "git+https://github.com/project-serum/anchor?branch=armani/solana#5925ed85289ddb43eb1266417f72b7f5433afac3" dependencies = [ "anyhow", "bs58 0.3.1", @@ -522,6 +522,7 @@ version = "0.1.0" dependencies = [ "anchor-lang", "anchor-spl", + "spl-governance", ] [[package]] @@ -995,7 +996,7 @@ dependencies = [ "safe-transmute", "serde", "solana-program", - "spl-token", + "spl-token 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "static_assertions", "thiserror", "without-alloc", @@ -1028,9 +1029,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.7.11" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21ddfc2b65a555c0e0156c043bce092d473bc4f00daa7ca3c223d97d92d2e807" +checksum = "2701ac3f93f76c1be615e2f9d5d7a60ab7955f8c2852dbb9e7208f8463bfd36f" dependencies = [ "bs58 0.3.1", "bv", @@ -1048,9 +1049,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.7.11" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a876aa31298fdee6560c8ee0695ebed313bbdbb6fbbee439ac3b9df8aebfb87c" +checksum = "918ae2b975c8c918a70babdd09d368d6c8fc0beccf7b8373a3d90bfeeddf9628" dependencies = [ "proc-macro2", "quote", @@ -1060,9 +1061,9 @@ dependencies = [ [[package]] name = "solana-logger" -version = "1.7.11" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98a07290cc521e529bff0b0afd3aacd1d3904a41f35321ede6d1f3574efa3e94" +checksum = "ba9e90da01bb0da7f10a1b195de09f52a00eeecf11e849a278104d814135a511" dependencies = [ "env_logger", "lazy_static", @@ -1071,9 +1072,9 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.7.11" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ffc60d33a318300682e42d28ff4f1276327f6374cab9591c8620a54be7aec1" +checksum = "283f672457a081e0f7a76283887575bfa3fe969efcb25cd5c6c3299ec0261a6f" dependencies = [ "bincode", "blake3", @@ -1106,9 +1107,9 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.7.11" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b453dca160617b1676c47e3cfd4361f455dc5bb1c93659ec84b0c5d566b5c039" +checksum = "ec0b5edf33d59c47d5f71583e08f8e9845716302f49301ed696e065fbbfb9e79" dependencies = [ "bs58 0.3.1", "proc-macro2", @@ -1124,7 +1125,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "393e2240d521c3dd770806bff25c2c00d761ac962be106e14e22dd912007f428" dependencies = [ "solana-program", - "spl-token", + "spl-token 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "spl-governance" +version = "2.1.1" +source = "git+https://github.com/solana-labs/solana-program-library#e8b7009cc4d8cdd87232ccfc9ce93ab203ada496" +dependencies = [ + "arrayref", + "bincode", + "borsh", + "num-derive", + "num-traits", + "serde", + "serde_derive", + "solana-program", + "spl-token 3.2.0 (git+https://github.com/solana-labs/solana-program-library)", + "thiserror", ] [[package]] @@ -1141,6 +1159,19 @@ dependencies = [ "thiserror", ] +[[package]] +name = "spl-token" +version = "3.2.0" +source = "git+https://github.com/solana-labs/solana-program-library#e8b7009cc4d8cdd87232ccfc9ce93ab203ada496" +dependencies = [ + "arrayref", + "num-derive", + "num-traits", + "num_enum", + "solana-program", + "thiserror", +] + [[package]] name = "static_assertions" version = "1.1.0" diff --git a/package.json b/package.json index 5ffc20f..250c94e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,12 @@ { + "scripts": { + "test": "anchor test" + }, "dependencies": { "@project-serum/anchor": "^0.17.1-beta.1", - "@solana/spl-token": "^0.1.8" + "@project-serum/common": "^0.0.1-beta.3", + "@solana/spl-token": "^0.1.8", + "bn.js": "^5.2.0" }, "devDependencies": { "@types/mocha": "^9.0.0", diff --git a/programs/governance-registry/Cargo.toml b/programs/governance-registry/Cargo.toml index 18cb559..fdcebdc 100644 --- a/programs/governance-registry/Cargo.toml +++ b/programs/governance-registry/Cargo.toml @@ -16,9 +16,6 @@ default = [] [dependencies] # TODO: use versions after next Anchor publish. -anchor-lang = { path = "../../../anchor/lang" } -anchor-spl = { path = "../../../anchor/spl" } -#anchor-lang = { git = "https://github.com/project-serum/anchor", branch = "armani/solana" } -#anchor-spl = { git = "https://github.com/project-serum/anchor", branch = "armani/solana" } -#spl-governance = { git = "https://github.com/solana-labs/solana-program-library" } -spl-governance = { path = "../../../../solana-labs/solana-program-library/governance/program", features=["no-entrypoint"] } +anchor-lang = { git = "https://github.com/project-serum/anchor", branch = "armani/solana" } +anchor-spl = { git = "https://github.com/project-serum/anchor", branch = "armani/solana" } +spl-governance = { git = "https://github.com/solana-labs/solana-program-library", features = ["no-entrypoint"] } diff --git a/programs/governance-registry/src/lib.rs b/programs/governance-registry/src/lib.rs index d9e16d6..946427f 100644 --- a/programs/governance-registry/src/lib.rs +++ b/programs/governance-registry/src/lib.rs @@ -23,7 +23,7 @@ pub mod governance_registry { _voting_mint_decimals: u8, ) -> Result<()> { let registrar = &mut ctx.accounts.registrar.load_init()?; - registrar.registrar_bump = registrar_bump; + registrar.bump = registrar_bump; registrar.voting_mint_bump = voting_mint_bump; registrar.realm = ctx.accounts.realm.key(); registrar.voting_mint = ctx.accounts.voting_mint.key(); @@ -35,7 +35,7 @@ pub mod governance_registry { /// Creates a new voter account. There can only be a single voter per /// user wallet. pub fn init_voter(ctx: Context, voter_bump: u8) -> Result<()> { - let voter = &mut ctx.accounts.voter.load_mut()?; + let voter = &mut ctx.accounts.voter.load_init()?; voter.voter_bump = voter_bump; voter.authority = ctx.accounts.authority.key(); voter.registrar = ctx.accounts.registrar.key(); @@ -48,6 +48,10 @@ pub mod governance_registry { /// exchange rate per mint. pub fn add_exchange_rate(ctx: Context, er: ExchangeRateEntry) -> Result<()> { require!(er.rate > 0, InvalidRate); + + let mut er = er; + er.is_used = false; + let registrar = &mut ctx.accounts.registrar.load_mut()?; let idx = registrar .rates @@ -95,16 +99,31 @@ pub mod governance_registry { Some(e) => &mut voter.deposits[e], } }; + + // Update the amount deposited. deposit_entry.amount += amount; - // Calculate the amount of voting tokens to mint. + // Calculate the amount of voting tokens to mint at the specified + // exchange rate. let scaled_amount = er_entry.rate * amount; // Deposit tokens into the registrar. - token::transfer((&*ctx.accounts).into(), amount)?; + token::transfer(ctx.accounts.transfer_ctx(), amount)?; // Mint vote tokens to the depositor. - token::mint_to((&*ctx.accounts).into(), scaled_amount)?; + token::mint_to( + ctx.accounts + .mint_to_ctx() + .with_signer(&[&[registrar.realm.as_ref(), &[registrar.bump]]]), + scaled_amount, + )?; + + // Freeze the vote tokens; they are just used for UIs + accounting. + token::freeze_account( + ctx.accounts + .freeze_ctx() + .with_signer(&[&[registrar.realm.as_ref(), &[registrar.bump]]]), + )?; Ok(()) } @@ -162,13 +181,11 @@ pub struct InitRegistrar<'info> { payer = payer, mint::authority = registrar, mint::decimals = voting_mint_decimals, - mint::freeze_authority = freeze_authority, + mint::freeze_authority = registrar, )] voting_mint: Account<'info, Mint>, realm: UncheckedAccount<'info>, authority: UncheckedAccount<'info>, - #[account(seeds = [b"freeze"], bump)] - freeze_authority: UncheckedAccount<'info>, payer: Signer<'info>, system_program: Program<'info, System>, token_program: Program<'info, Token>, @@ -183,13 +200,23 @@ pub struct InitVoter<'info> { seeds = [registrar.key().as_ref(), authority.key().as_ref()], bump = voter_bump, payer = authority, - space = 8 + size_of::() + space = 8 + size_of::(), )] voter: AccountLoader<'info, Voter>, - // todo: init voting toiken + #[account( + init, + payer = authority, + associated_token::authority = authority, + associated_token::mint = voting_mint, + )] + voting_token: Account<'info, TokenAccount>, + voting_mint: Account<'info, Mint>, registrar: AccountLoader<'info, Registrar>, authority: Signer<'info>, + token_program: Program<'info, Token>, + associated_token_program: Program<'info, AssociatedToken>, system_program: Program<'info, System>, + rent: Sysvar<'info, Rent>, } #[derive(Accounts)] @@ -203,7 +230,7 @@ pub struct AddExchangeRate<'info> { )] exchange_vault: Account<'info, TokenAccount>, deposit_mint: Account<'info, Mint>, - #[account(has_one = authority)] + #[account(mut, has_one = authority)] registrar: AccountLoader<'info, Registrar>, authority: Signer<'info>, payer: Signer<'info>, @@ -215,28 +242,64 @@ pub struct AddExchangeRate<'info> { #[derive(Accounts)] pub struct Deposit<'info> { - #[account(has_one = authority)] + #[account(mut, has_one = authority)] voter: AccountLoader<'info, Voter>, #[account( + mut, associated_token::authority = registrar, associated_token::mint = deposit_mint, )] exchange_vault: Account<'info, TokenAccount>, #[account( + mut, constraint = deposit_token.mint == deposit_mint.key(), )] deposit_token: Account<'info, TokenAccount>, #[account( + mut, constraint = registrar.load()?.voting_mint == voting_token.mint, )] voting_token: Account<'info, TokenAccount>, authority: Signer<'info>, registrar: AccountLoader<'info, Registrar>, deposit_mint: Account<'info, Mint>, + #[account(mut)] voting_mint: Account<'info, Mint>, token_program: Program<'info, Token>, } +impl<'info> Deposit<'info> { + fn transfer_ctx(&self) -> CpiContext<'_, '_, '_, 'info, token::Transfer<'info>> { + let program = self.token_program.to_account_info(); + let accounts = token::Transfer { + from: self.deposit_token.to_account_info(), + to: self.exchange_vault.to_account_info(), + authority: self.authority.to_account_info(), + }; + CpiContext::new(program, accounts) + } + + fn mint_to_ctx(&self) -> CpiContext<'_, '_, '_, 'info, token::MintTo<'info>> { + let program = self.token_program.to_account_info(); + let accounts = token::MintTo { + mint: self.voting_mint.to_account_info(), + to: self.voting_token.to_account_info(), + authority: self.registrar.to_account_info(), + }; + CpiContext::new(program, accounts) + } + + fn freeze_ctx(&self) -> CpiContext<'_, '_, '_, 'info, token::FreezeAccount<'info>> { + let program = self.token_program.to_account_info(); + let accounts = token::FreezeAccount { + account: self.voting_token.to_account_info(), + mint: self.voting_mint.to_account_info(), + authority: self.registrar.to_account_info(), + }; + CpiContext::new(program, accounts) + } +} + #[derive(Accounts)] pub struct Withdraw { // todo @@ -270,7 +333,7 @@ pub struct Registrar { pub realm: Pubkey, pub voting_mint: Pubkey, pub voting_mint_bump: u8, - pub registrar_bump: u8, + pub bump: u8, pub rates: [ExchangeRateEntry; 32], } @@ -387,29 +450,3 @@ pub enum ErrorCode { DepositEntryFull, VotingTokenNonZero, } - -// CpiContext. - -impl<'info> From<&Deposit<'info>> for CpiContext<'_, '_, '_, 'info, token::Transfer<'info>> { - fn from(accs: &Deposit<'info>) -> Self { - let program = accs.token_program.to_account_info(); - let accounts = token::Transfer { - from: accs.deposit_token.to_account_info(), - to: accs.exchange_vault.to_account_info(), - authority: accs.registrar.to_account_info(), - }; - CpiContext::new(program, accounts) - } -} - -impl<'info> From<&Deposit<'info>> for CpiContext<'_, '_, '_, 'info, token::MintTo<'info>> { - fn from(accs: &Deposit<'info>) -> Self { - let program = accs.token_program.to_account_info(); - let accounts = token::MintTo { - mint: accs.voting_mint.to_account_info(), - to: accs.voting_token.to_account_info(), - authority: accs.registrar.to_account_info(), - }; - CpiContext::new(program, accounts) - } -} diff --git a/tests/governance-registry.ts b/tests/governance-registry.ts index c982dc4..4250aef 100644 --- a/tests/governance-registry.ts +++ b/tests/governance-registry.ts @@ -1,7 +1,10 @@ +import * as assert from 'assert'; import * as anchor from '@project-serum/anchor'; import { Program } from '@project-serum/anchor'; +import { createMintAndVault } from '@project-serum/common'; +import BN from 'bn.js'; import { PublicKey, Keypair, SystemProgram, SYSVAR_RENT_PUBKEY } from '@solana/web3.js'; -import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; +import { Token, TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { GovernanceRegistry } from '../target/types/governance_registry'; describe('voting-rights', () => { @@ -9,74 +12,166 @@ describe('voting-rights', () => { const program = anchor.workspace.GovernanceRegistry as Program; - // Initialized variables shared across tests. - const realm = Keypair.generate().publicKey; - const votingMintDecimals = 6; + // Initialized variables shared across tests. + const realm = Keypair.generate().publicKey; + const votingMintDecimals = 6; + const tokenProgram = TOKEN_PROGRAM_ID; + const associatedTokenProgram = ASSOCIATED_TOKEN_PROGRAM_ID; + const rent = SYSVAR_RENT_PUBKEY; + const systemProgram = SystemProgram.programId; - // Uninitialized variables shared across tests. - let registrar: PublicKey, votingMint: PublicKey, voter: PublicKey; - let registrarBump: number, votingMintBump: number, voterBump: number; + // Uninitialized variables shared across tests. + let registrar: PublicKey, + votingMint: PublicKey, + voter: PublicKey, + votingToken: PublicKey, + exchangeVaultA: PublicKey, + exchangeVaultB: PublicKey; + let registrarBump: number, votingMintBump: number, voterBump: number; + let mintA: PublicKey, mintB: PublicKey, godA: PublicKey, godB: PublicKey; - it('Creates PDAs', async () => { - const [_registrar, _registrarBump] = await PublicKey.findProgramAddress( - [realm.toBuffer()], - program.programId, - ); - const [_votingMint, _votingMintBump] = await PublicKey.findProgramAddress( - [_registrar.toBuffer()], - program.programId, - ); - const [_voter, _voterBump] = await PublicKey.findProgramAddress( - [_registrar.toBuffer(), program.provider.wallet.publicKey.toBuffer()], - program.programId, - ); + it('Creates tokens and mints', async () => { + const decimals = 6; + const [_mintA, _godA] = await createMintAndVault( + program.provider, + new BN("1000000000000000000"), + undefined, + decimals + ); + const [_mintB, _godB] = await createMintAndVault( + program.provider, + new BN("1000000000000000000"), + undefined, + decimals + ); - registrar = _registrar; - votingMint = _votingMint; - voter = _voter; - - registrarBump = _registrarBump; - votingMintBump = _votingMintBump; - voterBump = _voterBump; - }); - - it('Initializes a registrar', async () => { - await program.rpc.initRegistrar(registrarBump, votingMintBump, votingMintDecimals, { - accounts: { - registrar, - votingMint, - realm, - authority: program.provider.wallet.publicKey, - payer: program.provider.wallet.publicKey, - systemProgram: SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, - rent: SYSVAR_RENT_PUBKEY, - } - }); - - const registrarAccount = await program.account.registrar.fetch(registrar); - console.log(registrarAccount); + mintA = _mintA; + mintB = _mintB; + godA = _godA; + godB = _godB; }); - it('Initializes a voter', async () => { - await program.rpc.initVoter(voterBump, { - accounts: { - voter, - registrar, - authority: program.provider.wallet.publicKey, - systemProgram: SystemProgram.programId, - } - }); + it('Creates PDAs', async () => { + const [_registrar, _registrarBump] = await PublicKey.findProgramAddress( + [realm.toBuffer()], + program.programId, + ); + const [_votingMint, _votingMintBump] = await PublicKey.findProgramAddress( + [_registrar.toBuffer()], + program.programId, + ); + const [_voter, _voterBump] = await PublicKey.findProgramAddress( + [_registrar.toBuffer(), program.provider.wallet.publicKey.toBuffer()], + program.programId, + ); + votingToken = await Token.getAssociatedTokenAddress( + associatedTokenProgram, + tokenProgram, + _votingMint, + program.provider.wallet.publicKey, + ); + exchangeVaultA = await Token.getAssociatedTokenAddress( + associatedTokenProgram, + tokenProgram, + mintA, + _registrar, + true, + ); + exchangeVaultB = await Token.getAssociatedTokenAddress( + associatedTokenProgram, + tokenProgram, + mintB, + _registrar, + true, + ); - const voterAccount = await program.account.voter.fetch(voter); - console.log(voterAccount); - }); + registrar = _registrar; + votingMint = _votingMint; + voter = _voter; - it('Adds an exchange rate', async () => { + registrarBump = _registrarBump; + votingMintBump = _votingMintBump; + voterBump = _voterBump; + }); - }); + it('Initializes a registrar', async () => { + await program.rpc.initRegistrar(registrarBump, votingMintBump, votingMintDecimals, { + accounts: { + registrar, + votingMint, + realm, + authority: program.provider.wallet.publicKey, + payer: program.provider.wallet.publicKey, + systemProgram, + tokenProgram, + rent, + }, + }); + }); - it('Mints voting rights', async () => { + it('Initializes a voter', async () => { + await program.rpc.initVoter(voterBump, { + accounts: { + voter, + votingToken, + votingMint, + registrar, + authority: program.provider.wallet.publicKey, + systemProgram, + associatedTokenProgram, + tokenProgram, + rent, + } + }); + }); - }); + it('Adds an exchange rate', async () => { + const er = { + isUsed: false, + mint: mintA, + rate: new BN(1), + } + await program.rpc.addExchangeRate(er, { + accounts: { + exchangeVault: exchangeVaultA, + depositMint: mintA, + registrar, + authority: program.provider.wallet.publicKey, + payer: program.provider.wallet.publicKey, + rent, + tokenProgram, + associatedTokenProgram, + systemProgram, + } + }) + }); + + it('Deposits unlocked A tokens', async () => { + const amount = new BN(10); + await program.rpc.deposit(amount, { + accounts: { + voter, + exchangeVault: exchangeVaultA, + depositToken: godA, + votingToken, + authority: program.provider.wallet.publicKey, + registrar, + depositMint: mintA, + votingMint, + tokenProgram, + }, + }); + const voterAccount = await program.account.voter.fetch(voter); + console.log(voterAccount); + + + }); + + it ('Deposits locked tokens', async () => { + + }); + + it('Mints voting rights', async () => { + + }); }); diff --git a/yarn.lock b/yarn.lock index 6f3b25b..2a45239 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,6 +9,26 @@ dependencies: regenerator-runtime "^0.13.4" +"@project-serum/anchor@^0.11.1": + version "0.11.1" + resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.11.1.tgz#155bff2c70652eafdcfd5559c81a83bb19cec9ff" + integrity sha512-oIdm4vTJkUy6GmE6JgqDAuQPKI7XM4TPJkjtoIzp69RZe0iAD9JP2XHx7lV1jLdYXeYHqDXfBt3zcq7W91K6PA== + dependencies: + "@project-serum/borsh" "^0.2.2" + "@solana/web3.js" "^1.17.0" + base64-js "^1.5.1" + bn.js "^5.1.2" + bs58 "^4.0.1" + buffer-layout "^1.2.0" + camelcase "^5.3.1" + crypto-hash "^1.3.0" + eventemitter3 "^4.0.7" + find "^0.3.0" + js-sha256 "^0.9.0" + pako "^2.0.3" + snake-case "^3.0.4" + toml "^3.0.0" + "@project-serum/anchor@^0.17.1-beta.1": version "0.17.1-beta.1" resolved "https://registry.yarnpkg.com/@project-serum/anchor/-/anchor-0.17.1-beta.1.tgz#0532b4534c6a86e67e8530040c717979240f1dbe" @@ -37,6 +57,26 @@ bn.js "^5.1.2" buffer-layout "^1.2.0" +"@project-serum/common@^0.0.1-beta.3": + version "0.0.1-beta.3" + resolved "https://registry.yarnpkg.com/@project-serum/common/-/common-0.0.1-beta.3.tgz#53586eaff9d9fd7e8938b1e12080c935b8b6ad07" + integrity sha512-gnQE/eUydTtto5okCgLWj1M97R9RRPJqnhKklikYI7jP/pnNhDmngSXC/dmfzED2GXSJEIKNIlxVw1k+E2Aw3w== + dependencies: + "@project-serum/serum" "^0.13.21" + bn.js "^5.1.2" + superstruct "0.8.3" + +"@project-serum/serum@^0.13.21": + version "0.13.60" + resolved "https://registry.yarnpkg.com/@project-serum/serum/-/serum-0.13.60.tgz#abeb3355ebc1895d685250df5965f688502ebcbb" + integrity sha512-fGsp9F0ZAS48YQ2HNy+6CNoifJESFXxVsOLPd9QK1XNV8CTuQoECOnVXxV6s5cKGre8pLNq5hrhi5J6aCGauEQ== + dependencies: + "@project-serum/anchor" "^0.11.1" + "@solana/spl-token" "^0.1.6" + "@solana/web3.js" "^1.21.0" + bn.js "^5.1.2" + buffer-layout "^1.2.0" + "@solana/buffer-layout@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz#b9353caeb9a1589cb77a1b145bcb1a9a93114326" @@ -44,7 +84,7 @@ dependencies: buffer "~6.0.3" -"@solana/spl-token@^0.1.8": +"@solana/spl-token@^0.1.6", "@solana/spl-token@^0.1.8": version "0.1.8" resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.1.8.tgz#f06e746341ef8d04165e21fc7f555492a2a0faa6" integrity sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ== @@ -246,7 +286,7 @@ bn.js@^4.11.9: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.0.0, bn.js@^5.1.0, bn.js@^5.1.2: +bn.js@^5.0.0, bn.js@^5.1.0, bn.js@^5.1.2, bn.js@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== @@ -746,6 +786,11 @@ jsonparse@^1.2.0: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + locate-path@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -1048,6 +1093,14 @@ strip-json-comments@3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +superstruct@0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.8.3.tgz#fb4d8901aca3bf9f79afab1bbab7a7f335cc4ef2" + integrity sha512-LbtbFpktW1FcwxVIJlxdk7bCyBq/GzOx2FSFLRLTUhWIA1gHkYPIl3aXRG5mBdGZtnPNT6t+4eEcLDCMOuBHww== + dependencies: + kind-of "^6.0.2" + tiny-invariant "^1.0.6" + superstruct@^0.14.2: version "0.14.2" resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" @@ -1077,6 +1130,11 @@ text-encoding-utf-8@^1.0.2: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= +tiny-invariant@^1.0.6: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" + integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"