2021-12-04 01:51:47 -08:00
|
|
|
use anchor_spl::token::TokenAccount;
|
|
|
|
use program_test::*;
|
|
|
|
use solana_program_test::*;
|
2021-12-05 00:04:04 -08:00
|
|
|
use solana_sdk::{signature::Keypair, signer::Signer, transport::TransportError};
|
2021-12-04 01:51:47 -08:00
|
|
|
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], 2)
|
|
|
|
.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,
|
|
|
|
&token_owner_record,
|
|
|
|
&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,
|
|
|
|
&token_owner_record,
|
|
|
|
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,
|
|
|
|
&token_owner_record,
|
|
|
|
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,
|
|
|
|
&token_owner_record,
|
|
|
|
&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,
|
|
|
|
&token_owner_record2,
|
|
|
|
&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,
|
|
|
|
&token_owner_record2,
|
|
|
|
&mngo_voting_mint,
|
|
|
|
&voter2_authority,
|
|
|
|
voter_mngo,
|
|
|
|
0,
|
|
|
|
1,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.expect_err("could not withdraw");
|
|
|
|
|
|
|
|
realm
|
|
|
|
.relinquish_vote(
|
|
|
|
mint_governance.address,
|
|
|
|
&proposal,
|
|
|
|
&token_owner_record2,
|
|
|
|
&voter2_authority,
|
|
|
|
payer.pubkey(),
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// can withdraw again
|
|
|
|
addin
|
|
|
|
.withdraw(
|
|
|
|
®istrar,
|
|
|
|
&voter2,
|
|
|
|
&token_owner_record2,
|
|
|
|
&mngo_voting_mint,
|
|
|
|
&voter2_authority,
|
|
|
|
voter_mngo,
|
|
|
|
0,
|
|
|
|
750,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|