use anchor_spl::token::TokenAccount; use program_test::*; use solana_program_test::*; use solana_sdk::{signature::Keypair, signer::Signer, transport::TransportError}; use voter_stake_registry::state::LockupKind; mod program_test; #[allow(unaligned_references)] #[tokio::test] async fn test_voting() -> Result<(), TransportError> { let context = TestContext::new().await; let addin = &context.addin; let payer = &context.users[0].key; let realm_authority = Keypair::new(); let realm = context .governance .create_realm( "testrealm", realm_authority.pubkey(), &context.mints[0], &payer, &context.addin.program_id, ) .await; let voter_authority = &context.users[1].key; let voter2_authority = &context.users[2].key; let voter_mngo = context.users[1].token_accounts[0]; let token_owner_record = realm .create_token_owner_record(voter_authority.pubkey(), &payer) .await; let token_owner_record2 = realm .create_token_owner_record(voter2_authority.pubkey(), &payer) .await; let registrar = addin .create_registrar(&realm, &realm_authority, payer) .await; let mngo_voting_mint = addin .configure_voting_mint( ®istrar, &realm_authority, payer, 0, &context.mints[0], 0, 2.0, 0.0, 5 * 365 * 24 * 60 * 60, None, ) .await; let voter = addin .create_voter(®istrar, &token_owner_record, &voter_authority, &payer) .await; let voter2 = addin .create_voter(®istrar, &token_owner_record2, &voter2_authority, &payer) .await; let mint_governance = realm .create_mint_governance( context.mints[0].pubkey.unwrap(), &context.mints[0].authority, &voter, &voter_authority, payer, addin.update_voter_weight_record_instruction(®istrar, &voter), ) .await; addin .create_deposit_entry( ®istrar, &voter, voter_authority, &mngo_voting_mint, 0, LockupKind::None, 0, false, ) .await .unwrap(); addin .deposit( ®istrar, &voter, &mngo_voting_mint, voter_authority, voter_mngo, 0, 499, ) .await .unwrap(); // need vote weight of 1000, but only have 499 * 2 realm .create_proposal( mint_governance.address, &voter_authority, &voter, payer, addin.update_voter_weight_record_instruction(®istrar, &voter), ) .await .expect_err("not enough tokens to create proposal"); addin .deposit( ®istrar, &voter, &mngo_voting_mint, voter_authority, voter_mngo, 0, 1, ) .await .unwrap(); context.solana.advance_clock_by_slots(2).await; // avoid cache when sending same transaction again let proposal = realm .create_proposal( mint_governance.address, &voter_authority, &voter, payer, addin.update_voter_weight_record_instruction(®istrar, &voter), ) .await .unwrap(); // having created a proposal, withdrawing is impossible context.solana.advance_clock_by_slots(2).await; // avoid cache when sending same transaction again addin .withdraw( ®istrar, &voter, &mngo_voting_mint, &voter_authority, voter_mngo, 0, 1, ) .await .expect_err("could not withdraw"); addin .create_deposit_entry( ®istrar, &voter2, voter2_authority, &mngo_voting_mint, 0, LockupKind::None, 0, false, ) .await .unwrap(); addin .deposit( ®istrar, &voter2, &mngo_voting_mint, voter_authority, voter_mngo, 0, 750, ) .await .unwrap(); realm .cast_vote( mint_governance.address, &proposal, &voter2, &voter2_authority, payer, addin.update_voter_weight_record_instruction(®istrar, &voter2), ) .await .unwrap(); let proposal_data = context.solana.get_account_data(proposal.address).await; let mut data_slice: &[u8] = &proposal_data; let proposal_state: spl_governance::state::proposal::Proposal = anchor_lang::AnchorDeserialize::deserialize(&mut data_slice).unwrap(); assert_eq!(proposal_state.yes_votes_count, 2 * 750); assert_eq!(proposal_state.no_votes_count, 0); // having voted, the funds are now locked, withdrawing is impossible context.solana.advance_clock_by_slots(2).await; // avoid cache when sending same transaction again addin .withdraw( ®istrar, &voter2, &mngo_voting_mint, &voter2_authority, voter_mngo, 0, 1, ) .await .expect_err("could not withdraw"); realm .relinquish_vote( mint_governance.address, &proposal, voter2.token_owner_record, &voter2_authority, payer.pubkey(), ) .await .unwrap(); // can withdraw again addin .withdraw( ®istrar, &voter2, &mngo_voting_mint, &voter2_authority, voter_mngo, 0, 750, ) .await .unwrap(); Ok(()) }