Skip to content

Conversation

@linguists
Copy link
Contributor

@linguists linguists commented Jul 22, 2025

Update Voting Rules

  1. No more votes are allowed after deadline passes;
  2. No voting result until deadline is reached. The voting result will be concluded in the first ping() after deadline;
  3. The proposal will pass if both conditions are satisfied:
    1. total voted stake > 1/3 of total validator stake
    2. stake voted with YES > 2/3 of total voted stake

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Added tracking of both vote type and stake for each voter, allowing more detailed vote accounting.
    • Introduced a new event for proposal rejections with detailed stake and vote counts.
    • Proposal approval and rejection events now include the amount of "yes" stake and other voting metrics.
  • Improvements

    • Refined proposal approval conditions to consider both total voted stake and the proportion of "yes" votes.
    • Enhanced accuracy in stake calculations and event reporting.
    • Enforced voting deadline on vote submissions while allowing stake updates after the deadline.
  • Tests

    • Updated tests to reflect new vote data structures and approval/rejection logic.
    • Added tests verifying correct stake tracking and proposal rejection scenarios.
  • Chores

    • Updated build and test commands in README.
    • Streamlined Makefile targets by removing redundant test dependency.
    • Updated version number to 0.2.0.
  • Scripts

    • Improved test scripts with dynamic environment variables and expanded validator setup.
    • Adjusted voting script to use updated voting account and parameters.

@coderabbitai
Copy link

coderabbitai bot commented Jul 22, 2025

Walkthrough

The changes introduce a new VotedStake struct to track both the vote type and stake per voter, update the contract's vote storage and accounting logic, and refine proposal approval conditions. The ProposalApproved event now includes a yes_stake field, and a new ProposalRejected event variant is added. Voting and proposal approval logic is updated throughout to support these changes.

Changes

File(s) Change Summary
src/events.rs Added new ProposalRejected variant with detailed stake and vote count fields; added yes_stake, num_votes_yes, and num_votes_total fields to ProposalApproved variant.
src/lib.rs Introduced VotedStake struct; updated votes map to store VotedStake; added yes_stake field; changed result from Option<Timestamp> to Option<bool>; revised voting, ping, and proposal approval logic; updated event emission and view methods; adjusted tests accordingly.
tests/test_vote.rs Updated test deserialization of votes from HashMap<AccountId, String> to HashMap<AccountId, (Vote, U128)>; adjusted imports and assertions to reflect new vote and stake tuple structure; no changes to public entities.
tests/scripts/create-proposal.sh Updated environment variables for voting account and deadline; modified contract deployment command to use explicit wasm path.
tests/scripts/create-validators.sh Changed voting account ID; updated validator account naming and iteration range; adjusted staking pool wasm path.
tests/scripts/vote.sh Changed voting account ID; reduced loop iterations; updated validator ID prefix; changed contract call arguments and caller account.
README.md Updated build and test instructions to use make and make test instead of cargo near build and cargo test.
makefile Removed validator-voting-test from the all target dependencies, so make all runs only lint and validator-voting.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Contract
    participant Events

    User->>Contract: Casts vote (internal_vote)
    Contract->>Contract: Update votes map with VotedStake (vote + stake)
    Contract->>Contract: Update total_voted_stake and yes_stake
    User->>Contract: Calls ping
    Contract->>Contract: Recalculate stakes for all votes
    Contract->>Contract: Update total_voted_stake and yes_stake
    Contract->>Contract: Call check_result
    alt Approval conditions met
        Contract->>Events: Emit ProposalApproved with stake details
    else Rejection conditions met
        Contract->>Events: Emit ProposalRejected with stake details
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~45 minutes

Possibly related PRs

  • feat: vote with choice yes or no #6: Introduces explicit yes/no vote choices and updates events to include vote choice; this PR builds upon that feature by refining stake tracking and adding rejection events.
  • fix: vote from new staking pool contract #5: Modifies core voting logic including vote and ping methods; related by overlapping voting mechanism changes but focuses on staking pool ownership verification.
  • feat: validator voting contract #1: Introduces the initial validator voting contract and original event enum; this PR extends and modifies those foundational definitions.

Suggested reviewers

  • arkff202310
  • dongcool

Poem

In the meadow of code, where proposals awake,
Each bunny now counts both the vote and the stake.
With yes-stakes in paw and events in the air,
Approval or rejection hops forth with care.
Votes and stakes entwined, a dance so bright,
🐇✨ Coding by day, dreaming by night!

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 26f1aef and d7b63b9.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • Cargo.toml (1 hunks)
  • src/lib.rs (18 hunks)
  • tests/test_vote.rs (10 hunks)
✅ Files skipped from review due to trivial changes (1)
  • Cargo.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/test_vote.rs
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using `std::collections::HashMap` instead of `near_sdk::collections::UnorderedMap` or `LookupMap` for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.
src/lib.rs (2)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

Learnt from: linguists
PR: #1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using std::collections::HashMap instead of near_sdk::collections::UnorderedMap or LookupMap for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Tests
  • GitHub Check: Code Linter
🔇 Additional comments (9)
src/lib.rs (9)

18-31: Well-designed data structures for enhanced vote tracking.

The addition of PartialEq, Clone, and Debug traits to the Vote enum and the new VotedStake struct effectively support the updated voting logic. The structure combines vote choice with stake amount, enabling proper tracking of both vote type and associated stake per validator.


41-51: Contract state properly updated for new voting logic.

The contract state changes effectively support the enhanced voting requirements:

  • votes map now stores VotedStake for comprehensive vote tracking
  • yes_stake field enables efficient tracking of YES votes for approval calculations
  • result field appropriately changed from Option<Timestamp> to Option<bool>

56-73: Initialization properly updated.

The constructor correctly initializes the new yes_stake field to 0 while preserving all existing validation logic.


76-93: ping() method correctly implements stake updates after deadline.

The method properly resets and recalculates vote stakes based on current validator stakes, allowing for stake changes after the voting deadline as specified in the PR objectives. The logic correctly separates YES and NO vote stake tracking.


97-127: Vote method and callback properly maintained.

The addition of with_unused_gas_weight(0) follows NEAR SDK best practices, and the security validation in the callback method remains intact.


130-183: internal_vote() correctly implements deadline enforcement and stake accounting.

The method properly:

  • Enforces voting deadline as specified in PR objectives
  • Validates validator stake before allowing votes
  • Handles complex stake accounting for vote changes
  • Updates both total voted stake and YES stake tracking
  • Stores comprehensive vote information

The logic correctly handles switching between YES/NO votes and maintains accurate stake totals.


186-229: check_result() correctly implements new approval conditions.

The method properly enforces the updated voting rules:

  • Results are only determined after the deadline
  • Approval requires both >1/3 total validator participation AND >2/3 YES votes of participating stake
  • Comprehensive event emission for both approval and rejection scenarios

This implementation aligns perfectly with the PR objectives for stricter voting conditions.


234-275: View methods properly updated for new data structures.

The view methods correctly expose the enhanced vote tracking:

  • get_total_voted_stake() provides comprehensive stake breakdown including YES stake
  • get_votes() properly returns vote type with stake amounts
  • get_result() appropriately returns boolean approval status
  • Documentation accurately notes the need for ping() to update stake data

277-805: Comprehensive test coverage for updated voting logic.

The test suite thoroughly covers the enhanced voting functionality:

  • Deadline enforcement and post-deadline behavior
  • Stake tracking and epoch transitions
  • Vote switching and validator status changes
  • Proposal approval/rejection under various scenarios
  • Edge cases like validator kickout and re-entry

The tests properly validate the new voting rules and data structures, ensuring the implementation meets the PR objectives.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/update-voting-rules

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🔭 Outside diff range comments (2)
src/lib.rs (2)

18-23: Add missing Borsh serialization traits to the Vote enum

The Vote enum needs to implement Borsh serialization traits since it's used within VotedStake which requires both borsh and json serialization.

 #[near(serializers = [json])]
+#[derive(PartialEq)]
 #[serde(rename_all = "lowercase")]
 pub enum Vote {
     Yes,
     No,
 }

Additionally, update the #[near(serializers = [json])] annotation to include borsh:

-#[near(serializers = [json])]
+#[near(serializers = [borsh, json])]

214-218: Fix the conversion from VotedStake to U128

The code attempts to convert the entire VotedStake struct to U128, but should only convert the stake field.

 pub fn get_votes(&self) -> HashMap<AccountId, U128> {
     self.votes
         .iter()
-        .map(|(account_id, stake)| (account_id.clone(), (*stake).into()))
+        .map(|(account_id, voted_stake)| (account_id.clone(), voted_stake.stake.into()))
         .collect()
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a6c56c5 and 3e73c58.

📒 Files selected for processing (2)
  • src/events.rs (1 hunks)
  • src/lib.rs (6 hunks)
🧠 Learnings (3)
📓 Common learnings
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using `std::collections::HashMap` instead of `near_sdk::collections::UnorderedMap` or `LookupMap` for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.
src/events.rs (1)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

src/lib.rs (2)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

Learnt from: linguists
PR: #1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using std::collections::HashMap instead of near_sdk::collections::UnorderedMap or LookupMap for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.

🧬 Code Graph Analysis (1)
src/lib.rs (2)
src/utils.rs (2)
  • validator_stake (58-63)
  • validator_total_stake (65-70)
tests/contracts/mock-staking-pool/src/lib.rs (2)
  • vote (15-15)
  • vote (81-87)
🪛 GitHub Actions: Build
src/lib.rs

[error] 182-182: Cannot find value total_voted_stake in this scope. Did you mean self.total_voted_stake?


[error] 25-25: Trait BorshSerialize is not implemented for Vote. Required by #[near(serializers = [borsh, json])] macro.


[error] 25-25: Trait BorshDeserialize is not implemented for Vote. Required by #[near(serializers = [borsh, json])] macro.


[error] 27-27: Trait BorshSchema is not implemented for Vote used in field vote.


[error] 84-84: Binary operation == cannot be applied to type Vote. Missing implementation of PartialEq for Vote. Consider adding #[derive(PartialEq)].


[error] 142-142: Trait Default is not implemented for &VotedStake. unwrap_or_default() cannot be called on Option<&VotedStake>.


[error] 151-151: Binary operation == cannot be applied to type Vote. Missing implementation of PartialEq for Vote. Consider adding #[derive(PartialEq)].


[error] 217-217: Trait From<VotedStake> is not implemented for U128. Cannot convert VotedStake into U128.

🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using `std::collections::HashMap` instead of `near_sdk::collections::UnorderedMap` or `LookupMap` for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.
src/events.rs (1)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

src/lib.rs (2)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

Learnt from: linguists
PR: #1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using std::collections::HashMap instead of near_sdk::collections::UnorderedMap or LookupMap for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.

🧬 Code Graph Analysis (1)
src/lib.rs (2)
src/utils.rs (2)
  • validator_stake (58-63)
  • validator_total_stake (65-70)
tests/contracts/mock-staking-pool/src/lib.rs (2)
  • vote (15-15)
  • vote (81-87)
🪛 GitHub Actions: Build
src/lib.rs

[error] 182-182: Cannot find value total_voted_stake in this scope. Did you mean self.total_voted_stake?


[error] 25-25: Trait BorshSerialize is not implemented for Vote. Required by #[near(serializers = [borsh, json])] macro.


[error] 25-25: Trait BorshDeserialize is not implemented for Vote. Required by #[near(serializers = [borsh, json])] macro.


[error] 27-27: Trait BorshSchema is not implemented for Vote used in field vote.


[error] 84-84: Binary operation == cannot be applied to type Vote. Missing implementation of PartialEq for Vote. Consider adding #[derive(PartialEq)].


[error] 142-142: Trait Default is not implemented for &VotedStake. unwrap_or_default() cannot be called on Option<&VotedStake>.


[error] 151-151: Binary operation == cannot be applied to type Vote. Missing implementation of PartialEq for Vote. Consider adding #[derive(PartialEq)].


[error] 217-217: Trait From<VotedStake> is not implemented for U128. Cannot convert VotedStake into U128.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Code Linter
🔇 Additional comments (1)
src/events.rs (1)

23-31: Event structure properly updated

The addition of the yes_stake field to the ProposalApproved event correctly reflects the new voting mechanism that tracks yes votes separately.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f405792 and 58f801b.

📒 Files selected for processing (1)
  • src/lib.rs (16 hunks)
🧠 Learnings (2)
📓 Common learnings
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using `std::collections::HashMap` instead of `near_sdk::collections::UnorderedMap` or `LookupMap` for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.
src/lib.rs (2)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

Learnt from: linguists
PR: #1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using std::collections::HashMap instead of near_sdk::collections::UnorderedMap or LookupMap for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.

🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using `std::collections::HashMap` instead of `near_sdk::collections::UnorderedMap` or `LookupMap` for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.
src/lib.rs (2)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

Learnt from: linguists
PR: #1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using std::collections::HashMap instead of near_sdk::collections::UnorderedMap or LookupMap for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Code Linter
  • GitHub Check: Tests
🔇 Additional comments (14)
src/lib.rs (14)

18-24: LGTM: Vote enum properly configured for serialization and comparison.

The addition of PartialEq, Clone, and Debug traits along with Borsh and JSON serialization support is correctly implemented for the Vote enum.


26-30: LGTM: VotedStake struct properly designed.

The struct correctly encapsulates both vote type and stake amount, with appropriate serialization annotations.


46-49: LGTM: Contract state updated to support new voting logic.

The changes correctly:

  • Update votes map to store VotedStake instead of just Balance
  • Add yes_stake tracking for separate accounting
  • Change result from Option to Option

80-89: Verify stake accounting logic in ping method.

The ping method now resets both total_voted_stake and yes_stake to 0 and recalculates them. The logic looks correct but needs verification of the stake accounting.


130-134: LGTM: Voting deadline enforcement added correctly.

The addition of deadline checking in internal_vote is appropriate - voting should be prohibited after the deadline while allowing ping to update stakes.


137-141: LGTM: Validator stake validation is correct.

Properly validates that the account has positive stake before allowing voting.


143-158: LGTM: Stake calculation logic is sound.

The logic correctly:

  • Calculates yes stake contribution based on vote type
  • Retrieves previous vote and stake values
  • Handles the case where no previous vote exists

166-174: LGTM: Stake accounting and vote storage updated correctly.

The accounting logic properly:

  • Updates total_voted_stake by adding new stake and subtracting previous stake
  • Updates yes_stake by adding new yes contribution and subtracting previous yes contribution
  • Stores the new VotedStake entry

190-192: LGTM: Early return for deadline check is appropriate.

Correctly prevents result determination before the deadline has passed.


194-221: LGTM: Updated proposal approval logic and event emission.

The new logic correctly:

  • Requires total voted stake > 1/3 of total stake (quorum requirement)
  • Requires yes stake > 2/3 of total voted stake (supermajority of participants)
  • Sets result to true/false instead of timestamp
  • Emits appropriate ProposalApproved or ProposalRejected events with detailed metrics

230-236: LGTM: View method correctly returns stake tuple.

The method properly returns (yes_stake, total_voted_stake, total_stake) as documented.


241-251: LGTM: Vote retrieval method updated correctly.

Properly maps VotedStake entries to (Vote, stake) tuples for external consumption.


254-256: LGTM: Result method updated to return boolean.

Correctly returns Option instead of Option to match the new result semantics.


798-801: Verify test logic for validator vote changes.

The test shows validator 4 voting No, then Yes, but the vote count remains at 3. This suggests validator 4 was already in the votes map. Please verify this is the intended behavior.

This appears correct assuming the duplicate validator issue in line 784 is fixed - validator 4 changing their vote shouldn't increase the vote count.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🔭 Outside diff range comments (1)
tests/scripts/vote.sh (1)

11-15: Missing set -e can hide failed votes

If the first call reverts the script will still attempt to read totals, yielding misleading numbers.
The strict-mode guards recommended earlier (set -euo pipefail) apply here as well.

🧹 Nitpick comments (3)
tests/scripts/create-proposal.sh (1)

7-7: Dead code: commented account-creation leaves the script half-done

If the voting account does not exist beforehand the subsequent near contract deploy will fail.
Either delete the line entirely (less noise) or keep the command active and guard it with an idempotency check.

tests/scripts/create-validators.sh (1)

4-4: Consistent variable quoting

$VOTING_ACCOUNT_ID might one day contain characters that the shell expands (e.g., *).
Surround it with double quotes everywhere it is used, just like you already do for $VALIDATOR_ID.

tests/scripts/vote.sh (1)

5-9: Only one iteration – intentional?

for i in {1..1} loops exactly once; if this was meant to be a quick smoke test, consider dropping the loop entirely for clarity or restore the previous range.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b01dd9f and a289275.

📒 Files selected for processing (3)
  • tests/scripts/create-proposal.sh (1 hunks)
  • tests/scripts/create-validators.sh (1 hunks)
  • tests/scripts/vote.sh (1 hunks)
🧠 Learnings (4)
📓 Common learnings
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using `std::collections::HashMap` instead of `near_sdk::collections::UnorderedMap` or `LookupMap` for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.
tests/scripts/vote.sh (2)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

Learnt from: linguists
PR: #1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using std::collections::HashMap instead of near_sdk::collections::UnorderedMap or LookupMap for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.

tests/scripts/create-validators.sh (2)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

Learnt from: linguists
PR: #1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using std::collections::HashMap instead of near_sdk::collections::UnorderedMap or LookupMap for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.

tests/scripts/create-proposal.sh (1)

Learnt from: linguists
PR: #1
File: README.md:10-11
Timestamp: 2025-05-14T03:12:48.262Z
Learning: For NEAR contracts, cargo near build (non-reproducible-wasm) is acceptable for local development, while cargo near build reproducible-wasm is recommended for production builds that will be deployed.

🧬 Code Graph Analysis (1)
tests/scripts/create-proposal.sh (2)
tests/contracts/mock-staking-pool/src/lib.rs (1)
  • new (40-48)
src/lib.rs (1)
  • new (58-73)
🪛 Shellcheck (0.10.0)
tests/scripts/vote.sh

[warning] 6-6: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)

tests/scripts/create-validators.sh

[warning] 8-8: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)

🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using `std::collections::HashMap` instead of `near_sdk::collections::UnorderedMap` or `LookupMap` for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.
tests/scripts/vote.sh (2)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

Learnt from: linguists
PR: #1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using std::collections::HashMap instead of near_sdk::collections::UnorderedMap or LookupMap for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.

tests/scripts/create-validators.sh (2)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

Learnt from: linguists
PR: #1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using std::collections::HashMap instead of near_sdk::collections::UnorderedMap or LookupMap for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.

tests/scripts/create-proposal.sh (1)

Learnt from: linguists
PR: #1
File: README.md:10-11
Timestamp: 2025-05-14T03:12:48.262Z
Learning: For NEAR contracts, cargo near build (non-reproducible-wasm) is acceptable for local development, while cargo near build reproducible-wasm is recommended for production builds that will be deployed.

🧬 Code Graph Analysis (1)
tests/scripts/create-proposal.sh (2)
tests/contracts/mock-staking-pool/src/lib.rs (1)
  • new (40-48)
src/lib.rs (1)
  • new (58-73)
🪛 Shellcheck (0.10.0)
tests/scripts/vote.sh

[warning] 6-6: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)

tests/scripts/create-validators.sh

[warning] 8-8: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Code Linter
  • GitHub Check: Tests
🔇 Additional comments (1)
tests/scripts/create-validators.sh (1)

7-8: Brace expansion {4..10} is Bash-specific

The script declares #!/bin/bash, so this is OK locally, but portability to Dash/Zsh or CI environments that default to /bin/sh will break.
If portability matters use seq 4 10.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
makefile (1)

3-3: Declare explicit .PHONY targets to silence checkmake and avoid name-collision pitfalls

GNU make will treat all, lint, validator-voting, etc. as real files unless they’re marked phony, which can lead to confusing “Nothing to be done” messages if a file with the same name is ever created. checkmake is already warning about this.

+ .PHONY: all lint validator-voting validator-voting-test test
 all: lint validator-voting
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea1290b and b92179a.

📒 Files selected for processing (2)
  • README.md (1 hunks)
  • makefile (1 hunks)
🧠 Learnings (1)
📓 Common learnings
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using `std::collections::HashMap` instead of `near_sdk::collections::UnorderedMap` or `LookupMap` for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.
🪛 checkmake (0.2.2)
makefile

[warning] 3-3: Target "all" should be declared PHONY.

(phonydeclared)

✅ Files skipped from review due to trivial changes (1)
  • README.md
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using `std::collections::HashMap` instead of `near_sdk::collections::UnorderedMap` or `LookupMap` for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.
🪛 checkmake (0.2.2)
makefile

[warning] 3-3: Target "all" should be declared PHONY.

(phonydeclared)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Tests
  • GitHub Check: Code Linter
🔇 Additional comments (1)
makefile (1)

3-3: Confirm that dropping validator-voting-test from the default all target doesn’t break CI expectations

make test still builds validator-voting-test, but many CI pipelines invoke make all by default. If your pipeline previously relied on make all to compile the test Wasm, it will now silently skip that step.

Please verify the CI configuration (e.g., GitHub Actions, GitLab CI) and update it if necessary.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (4)
tests/scripts/create-validators.sh (1)

15-15: Manual JSON construction is error-prone (see prior review)
Still concatenating JSON by hand; any quote/back-slash in OWNER_ID et al. will break the payload. Previous review already proposed a jq -n refactor.

tests/scripts/vote.sh (1)

9-9: Unsafe JSON concatenation – switch to jq -n (previously flagged)
This remains the same manual concat pattern already called out earlier.

tests/scripts/create-proposal.sh (2)

1-1: Add strict-mode guards (previously suggested)
Still missing set -euo pipefail.


7-7: Manual JSON string building – same issue as before
Still vulnerable to quoting/escaping problems; migrate to jq -n.

Also applies to: 15-15

🧹 Nitpick comments (5)
tests/scripts/create-validators.sh (2)

1-1: Add strict-mode guards to avoid silent failures
This script touches live test-net accounts; exiting early on error is essential.

 #!/bin/bash
+set -euo pipefail
+IFS=$'\n\t'

6-6: Fragile quoting – SC2027
The mixed "..."$var"... pattern removes quoting around the expanded value, defeating the point of the quotes and tripping Shellcheck. Use a single quoted string with ${} interpolation.

-export VOTING_ACCOUNT_ID="mock-proposal-"$SUFFIX".testnet"
+export VOTING_ACCOUNT_ID="mock-proposal-${SUFFIX}.testnet"

-    VALIDATOR_ID="mock-node-"$SUFFIX"-"${i}".testnet"
+    VALIDATOR_ID="mock-node-${SUFFIX}-${i}.testnet"

Also applies to: 10-10

tests/scripts/vote.sh (2)

1-1: Enable strict mode for safer execution
Same rationale as the other scripts—abort on first error to protect funds.

 #!/bin/bash
+set -euo pipefail
+IFS=$'\n\t'

4-4: SC2027 – surrounding quotes unquote the variable
Adopt consistent ${} interpolation to keep the value quoted.

-export VOTING_ACCOUNT_ID="mock-proposal-"$SUFFIX".testnet"
+export VOTING_ACCOUNT_ID="mock-proposal-${SUFFIX}.testnet"

-    VALIDATOR_ID="mock-node-"$SUFFIX"-"${i}".testnet"
+    VALIDATOR_ID="mock-node-${SUFFIX}-${i}.testnet"

Also applies to: 7-7

tests/scripts/create-proposal.sh (1)

4-4: SC2027 – quoting issue for interpolated variable
Same pattern; keep the entire string quoted.

-export VOTING_ACCOUNT_ID="mock-proposal-"$SUFFIX".testnet"
+export VOTING_ACCOUNT_ID="mock-proposal-${SUFFIX}.testnet"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b92179a and 26f1aef.

📒 Files selected for processing (3)
  • tests/scripts/create-proposal.sh (1 hunks)
  • tests/scripts/create-validators.sh (1 hunks)
  • tests/scripts/vote.sh (1 hunks)
🧠 Learnings (3)
📓 Common learnings
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using `std::collections::HashMap` instead of `near_sdk::collections::UnorderedMap` or `LookupMap` for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.
tests/scripts/vote.sh (2)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

Learnt from: linguists
PR: #1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using std::collections::HashMap instead of near_sdk::collections::UnorderedMap or LookupMap for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.

tests/scripts/create-proposal.sh (1)

Learnt from: linguists
PR: #1
File: README.md:10-11
Timestamp: 2025-05-14T03:12:48.262Z
Learning: For NEAR contracts, cargo near build (non-reproducible-wasm) is acceptable for local development, while cargo near build reproducible-wasm is recommended for production builds that will be deployed.

🧬 Code Graph Analysis (1)
tests/scripts/create-validators.sh (2)
tests/contracts/mock-staking-pool/src/lib.rs (1)
  • new (40-48)
src/lib.rs (1)
  • new (58-73)
🪛 Shellcheck (0.10.0)
tests/scripts/vote.sh

[warning] 4-4: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)


[warning] 7-7: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)


[warning] 7-7: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)

tests/scripts/create-proposal.sh

[warning] 4-4: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)

tests/scripts/create-validators.sh

[warning] 6-6: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)


[warning] 10-10: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)


[warning] 10-10: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)

🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.
Learnt from: linguists
PR: linear-protocol/validator-voting-contract#1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using `std::collections::HashMap` instead of `near_sdk::collections::UnorderedMap` or `LookupMap` for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.
tests/scripts/vote.sh (2)

Learnt from: linguists
PR: #8
File: src/lib.rs:0-0
Timestamp: 2025-06-25T09:08:36.725Z
Learning: In the validator voting contract (src/lib.rs), the voting system intentionally handles "no" votes and zero-stake "yes" votes differently: validators who vote "no" are removed from the votes map and not re-inserted, while validators who voted "yes" but got kicked out (have 0 stake) are kept in the votes map with 0 stake to preserve their original voting intent. This asymmetric behavior in ping() vs internal_vote() is by design, not an inconsistency.

Learnt from: linguists
PR: #1
File: src/lib.rs:12-18
Timestamp: 2025-05-14T03:23:47.323Z
Learning: The team is aware of potential gas inefficiency with using std::collections::HashMap instead of near_sdk::collections::UnorderedMap or LookupMap for storing validator votes in the validator-voting contract. They plan to test the actual gas usage in integration tests in a future PR before deciding whether to implement this optimization.

tests/scripts/create-proposal.sh (1)

Learnt from: linguists
PR: #1
File: README.md:10-11
Timestamp: 2025-05-14T03:12:48.262Z
Learning: For NEAR contracts, cargo near build (non-reproducible-wasm) is acceptable for local development, while cargo near build reproducible-wasm is recommended for production builds that will be deployed.

🧬 Code Graph Analysis (1)
tests/scripts/create-validators.sh (2)
tests/contracts/mock-staking-pool/src/lib.rs (1)
  • new (40-48)
src/lib.rs (1)
  • new (58-73)
🪛 Shellcheck (0.10.0)
tests/scripts/vote.sh

[warning] 4-4: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)


[warning] 7-7: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)


[warning] 7-7: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)

tests/scripts/create-proposal.sh

[warning] 4-4: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)

tests/scripts/create-validators.sh

[warning] 6-6: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)


[warning] 10-10: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)


[warning] 10-10: The surrounding quotes actually unquote this. Remove or escape them.

(SC2027)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Tests
  • GitHub Check: Code Linter
🔇 Additional comments (1)
tests/scripts/create-proposal.sh (1)

9-9: Undefined variable ARGS – script prints nothing
echo $ARGS references a variable that is never set (should be INIT_ARGS).

-echo $ARGS
+echo "$INIT_ARGS"

Likely an incorrect or invalid review comment.

@linguists linguists merged commit 94356ba into main Jul 25, 2025
7 checks passed
@linguists linguists deleted the feat/update-voting-rules branch July 25, 2025 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants