Skip to content

feat: add half-life refill mode to RateLimiter and governance vote salt#795

Open
CodeNinjaStephen wants to merge 2 commits into
Predictify-org:masterfrom
CodeNinjaStephen:feature/halflife-rate-limiter-and-governance-salt
Open

feat: add half-life refill mode to RateLimiter and governance vote salt#795
CodeNinjaStephen wants to merge 2 commits into
Predictify-org:masterfrom
CodeNinjaStephen:feature/halflife-rate-limiter-and-governance-salt

Conversation

@CodeNinjaStephen

Copy link
Copy Markdown

Issue #660 — Half-life rate-limiter token replenishment • Add RefillMode enum { Linear, HalfLife(u64) } to rate_limiter.rs • RateLimitConfig gains refill_mode field (default: Linear, backwards compatible) • HalfLife mode: consumed tokens halve every half_life_seconds via integer
right-shift (no floats, no overflow, asymptotically approaches capacity)
• New RateLimiterError::InvalidHalfLife = 10 for zero or out-of-window values • validate_rate_limit_configuration rejects half_life=0 or half_life>time_window • check_limit_with_config and halflife_available added for mode-aware checks • get_rate_limit_status reports correct remaining for both modes • All existing RateLimitConfig literals updated with refill_mode: Linear • New: src/tests/rate_limiter_halflife_tests.rs (15 tests)

  • capacity enforcement, 1 half-life refill, full saturation (32+ shifts)
  • no overflow past capacity, monotone recovery, independent user/market buckets
  • validation (zero, >window rejected; valid passes), static-time no-refill
  • capacity-1 edge case, Linear→HalfLife config switch via update

Issue #668 — Governance proposal salt for vote-replay prevention • GovernanceProposal gains salt: BytesN<32> field
• Salt generated at creation via env.prng().gen() — never block timestamp • GovernanceContract::vote() now requires salt: BytesN<32> parameter;
rejects with GovernanceError::SaltMismatch when it does not match stored salt
• New GovernanceContract::get_proposal_salt() view function • GovernanceError::SaltMismatch added
• governance_tests.rs: BytesN import, vote helper auto-fetches correct salt,
get_salt/vote_with_salt helpers added to fixture
• 7 new salt tests: stored+retrievable, distinct per proposal, correct vote
passes, wrong salt rejected, replay prevention across resubmitted proposals,
ProposalNotFound for missing proposal, fixture helper works end-to-end

Pre-existing fix: market_id_generator.rs — add missing closing brace for impl MarketIdGenerator (unclosed delimiter; unrelated to these features)

Pull Request Description

📋 Basic Information

Type of Change

Please select the type of change this PR introduces:

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🧪 Test addition/update
  • 🔧 Refactoring (no functional changes)
  • ⚡ Performance improvement
  • 🔒 Security fix
  • 🎨 UI/UX improvement
  • 🚀 Deployment/Infrastructure change

Related Issues

Closes #(issue number)
Fixes #(issue number)
Related to #(issue number)

Priority Level

  • 🔴 Critical (blocking other development)
  • 🟡 High (significant impact)
  • 🟢 Medium (moderate impact)
  • 🔵 Low (minor improvement)

📝 Detailed Description

What does this PR do?

Why is this change needed?

How was this tested?

Alternative Solutions Considered


🏗️ Smart Contract Specific

Contract Changes

Please check all that apply:

  • Core contract logic modified
  • Oracle integration changes (Pyth/Reflector)
  • New functions added
  • Existing functions modified
  • Storage structure changes
  • Events added/modified
  • Error handling improved
  • Gas optimization
  • Access control changes
  • Admin functions modified
  • Fee structure changes

Oracle Integration

  • Pyth oracle integration affected
  • Reflector oracle integration affected
  • Oracle configuration changes
  • Price feed handling modified
  • Oracle fallback mechanisms
  • Price validation logic

Market Resolution Logic

  • Hybrid resolution algorithm changed
  • Dispute mechanism modified
  • Fee structure updated
  • Voting mechanism changes
  • Community weight calculation
  • Oracle weight calculation

Security Considerations

  • Access control reviewed
  • Reentrancy protection
  • Input validation
  • Overflow/underflow protection
  • Oracle manipulation protection

🧪 Testing

Test Coverage

  • Unit tests added/updated
  • Integration tests added/updated
  • All tests passing locally
  • Manual testing completed
  • Oracle integration tested
  • Edge cases covered
  • Error conditions tested
  • Gas usage optimized
  • Cross-contract interactions tested

Test Results

# Paste test output here
cargo test
# Expected output: X tests passed, Y tests failed

Manual Testing Steps


📚 Documentation

Documentation Updates

  • README updated
  • Code comments added/updated
  • API documentation updated
  • Examples updated
  • Deployment instructions updated
  • Contributing guidelines updated
  • Architecture documentation updated

Breaking Changes

Breaking Changes:

Migration Guide:


🔍 Code Quality

Code Review Checklist

  • Code follows Rust/Soroban best practices
  • Self-review completed
  • No unnecessary code duplication
  • Error handling is appropriate
  • Logging/monitoring added where needed
  • Security considerations addressed
  • Performance implications considered
  • Code is readable and well-commented
  • Variable names are descriptive
  • Functions are focused and small

Performance Impact

  • Gas Usage:
  • Storage Impact:
  • Computational Complexity:

Security Review

  • No obvious security vulnerabilities
  • Access controls properly implemented
  • Input validation in place
  • Oracle data properly validated
  • No sensitive data exposed

🚀 Deployment & Integration

Deployment Notes

  • Network: Testnet/Mainnet
  • Contract Address:
  • Migration Required: Yes/No
  • Special Instructions:

Integration Points

  • Frontend integration considered
  • API changes documented
  • Backward compatibility maintained
  • Third-party integrations updated

📊 Impact Assessment

User Impact

  • End Users:
  • Developers:
  • Admins:

Business Impact

  • Revenue:
  • User Experience:
  • Technical Debt:

✅ Final Checklist

Pre-Submission

  • Code follows Rust/Soroban best practices
  • All CI checks passing
  • No breaking changes (or breaking changes are documented)
  • Ready for review
  • PR description is complete and accurate
  • All required sections filled out
  • Test results included
  • Documentation updated

Review Readiness

  • Self-review completed
  • Code is clean and well-formatted
  • Commit messages are clear and descriptive
  • Branch is up to date with main
  • No merge conflicts

📸 Screenshots (if applicable)

🔗 Additional Resources

  • Design Document:
  • Technical Spec:
  • Related Discussion:
  • External Documentation:

💬 Notes for Reviewers

Please pay special attention to:

Questions for reviewers:


Thank you for your contribution to Predictify! 🚀

closes #660
closes #668

Issue Predictify-org#660 — Half-life rate-limiter token replenishment
• Add RefillMode enum { Linear, HalfLife(u64) } to rate_limiter.rs
• RateLimitConfig gains refill_mode field (default: Linear, backwards compatible)
• HalfLife mode: consumed tokens halve every half_life_seconds via integer
  right-shift (no floats, no overflow, asymptotically approaches capacity)
• New RateLimiterError::InvalidHalfLife = 10 for zero or out-of-window values
• validate_rate_limit_configuration rejects half_life=0 or half_life>time_window
• check_limit_with_config and halflife_available added for mode-aware checks
• get_rate_limit_status reports correct remaining for both modes
• All existing RateLimitConfig literals updated with refill_mode: Linear
• New: src/tests/rate_limiter_halflife_tests.rs (15 tests)
  - capacity enforcement, 1 half-life refill, full saturation (32+ shifts)
  - no overflow past capacity, monotone recovery, independent user/market buckets
  - validation (zero, >window rejected; valid passes), static-time no-refill
  - capacity-1 edge case, Linear→HalfLife config switch via update

Issue Predictify-org#668 — Governance proposal salt for vote-replay prevention
• GovernanceProposal gains salt: BytesN<32> field
• Salt generated at creation via env.prng().gen() — never block timestamp
• GovernanceContract::vote() now requires salt: BytesN<32> parameter;
  rejects with GovernanceError::SaltMismatch when it does not match stored salt
• New GovernanceContract::get_proposal_salt() view function
• GovernanceError::SaltMismatch added
• governance_tests.rs: BytesN import, vote helper auto-fetches correct salt,
  get_salt/vote_with_salt helpers added to fixture
• 7 new salt tests: stored+retrievable, distinct per proposal, correct vote
  passes, wrong salt rejected, replay prevention across resubmitted proposals,
  ProposalNotFound for missing proposal, fixture helper works end-to-end

Pre-existing fix: market_id_generator.rs — add missing closing brace for
impl MarketIdGenerator (unclosed delimiter; unrelated to these features)
@drips-wave

drips-wave Bot commented Jun 30, 2026

Copy link
Copy Markdown

@CodeNinjaStephen Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant