Skip to content

Commit 28d1f2e

Browse files
committed
Add timestamp check in CastVote instruction
1 parent 2ad5093 commit 28d1f2e

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

solana/programs/staking/src/error.rs

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ pub enum ErrorCode {
4949
ExceedsMaxAllowableVoteWeightWindowLength,
5050
#[msg("Invalid next voter checkpoints")]
5151
InvalidNextVoterCheckpoints,
52+
#[msg("Proposal inactive")]
53+
ProposalInactive,
5254
#[msg("Other")]
5355
Other,
5456
}

solana/programs/staking/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,12 @@ pub mod staking {
484484
let proposal = &mut ctx.accounts.proposal;
485485
let config = &ctx.accounts.config;
486486

487+
let current_timestamp: u64 = utils::clock::get_current_time().try_into()?;
487488
let vote_start = proposal.vote_start;
489+
require!(
490+
current_timestamp >= vote_start,
491+
ErrorCode::ProposalInactive
492+
);
488493

489494
let (_, window_length) = find_window_length_le(
490495
&ctx.accounts.vote_weight_window_lengths.to_account_info(),

solana/tests/api_test.ts

+55-2
Original file line numberDiff line numberDiff line change
@@ -876,17 +876,66 @@ describe("api", async () => {
876876
});
877877

878878
describe("castVote", () => {
879+
it("should fail to castVote if proposal inactive", async () => {
880+
await user6StakeConnection.delegate(
881+
user6,
882+
WHTokenBalance.fromString("50"),
883+
);
884+
885+
let proposalIdInput = await addTestProposal(
886+
user6StakeConnection,
887+
Math.floor(Date.now() / 1000) + 20,
888+
);
889+
890+
let stakeAccountMetadataAddress =
891+
await user6StakeConnection.getStakeMetadataAddress(
892+
user6StakeConnection.userPublicKey(),
893+
);
894+
let previousStakeAccountCheckpointsAddress =
895+
await user6StakeConnection.getStakeAccountCheckpointsAddressByMetadata(
896+
stakeAccountMetadataAddress,
897+
false,
898+
);
899+
900+
const { proposalAccount } =
901+
await user6StakeConnection.fetchProposalAccount(proposalIdInput);
902+
903+
try {
904+
await user6StakeConnection.program.methods
905+
.castVote(
906+
Array.from(proposalIdInput),
907+
new BN(10),
908+
new BN(20),
909+
new BN(12),
910+
0,
911+
)
912+
.accountsPartial({
913+
proposal: proposalAccount,
914+
voterCheckpoints: previousStakeAccountCheckpointsAddress,
915+
voterCheckpointsNext: null,
916+
})
917+
.rpc();
918+
919+
assert.fail("Expected an error but none was thrown");
920+
} catch (e) {
921+
assert(
922+
(e as AnchorError).error?.errorCode?.code === "ProposalInactive",
923+
);
924+
}
925+
});
926+
879927
it("should fail to castVote if votes were added in the voteWeightWindow", async () => {
880928
await user6StakeConnection.delegate(
881929
user6,
882-
WHTokenBalance.fromString("150"),
930+
WHTokenBalance.fromString("100"),
883931
);
884932

885933
// voteWeightWindow is 10s
886934
let proposalIdInput = await addTestProposal(
887935
user6StakeConnection,
888936
Math.floor(Date.now() / 1000) + 3,
889937
);
938+
await sleep(3000);
890939

891940
let stakeAccountMetadataAddress =
892941
await user6StakeConnection.getStakeMetadataAddress(
@@ -935,6 +984,7 @@ describe("api", async () => {
935984
user3StakeConnection,
936985
Math.floor(Date.now() / 1000) + 12,
937986
);
987+
await sleep(12000);
938988

939989
await user3StakeConnection.castVote(
940990
proposalIdInput,
@@ -979,6 +1029,7 @@ describe("api", async () => {
9791029
user4StakeConnection,
9801030
voteStart,
9811031
);
1032+
9821033
const { proposalAccount } =
9831034
await user4StakeConnection.fetchProposalAccount(proposalIdInput);
9841035

@@ -990,6 +1041,7 @@ describe("api", async () => {
9901041
WHTokenBalance.fromString("5"),
9911042
);
9921043
}
1044+
await sleep(4000);
9931045

9941046
let currentStakeAccountCheckpointsAddress =
9951047
await user4StakeConnection.getStakeAccountCheckpointsAddress(
@@ -1054,8 +1106,9 @@ describe("api", async () => {
10541106

10551107
let proposalIdInput = await addTestProposal(
10561108
user4StakeConnection,
1057-
Math.floor(Date.now() / 1000) + 12,
1109+
Math.floor(Date.now() / 1000) + 11,
10581110
);
1111+
await sleep(11000);
10591112

10601113
const { proposalAccount } =
10611114
await user4StakeConnection.fetchProposalAccount(proposalIdInput);

0 commit comments

Comments
 (0)