feat(contract): pool validations + multisig emergency cancel (#1119, #1122, #1130, #1131)#1308
Merged
Yunusabdul38 merged 1 commit intoJun 30, 2026
Conversation
…alabs#1119, Web3Novalabs#1122, Web3Novalabs#1130, Web3Novalabs#1131) Closes Web3Novalabs#1119, Web3Novalabs#1122, Web3Novalabs#1130, Web3Novalabs#1131. Issue Web3Novalabs#1122 — outcome description bounds: - New constants MAX_OUTCOME_DESCRIPTION_LEN (128) and MIN_OUTCOME_DESCRIPTION_LEN (1). - validate_pool_invariants now panics if any outcome description is empty or exceeds 128 bytes, preventing unbounded persistent-storage growth and useless empty labels. - New errors OutcomeDescriptionTooLong (130) and OutcomeDescriptionEmpty (131). Issue Web3Novalabs#1130 — staking deadlines must be in the future: - create_pool now returns the typed PredifiError::DeadlineInPast (132) when end_time < current_time, replacing the legacy assert string ("end_time must be in the future") which remains as a boundary diagnostic for end_time == current_time. - Non-zero start_time strictly in the past is also rejected. - start_time == 0 remains the "open immediately" sentinel. Issue Web3Novalabs#1131 — initial-liquidity safety margin: - New constant INITIAL_LIQUIDITY_SAFETY_MARGIN_BPS (100 = 1%). - When max_total_stake > 0, initial_liquidity must cover at least 1% of max_total_stake; otherwise PredifiError::InitialLiquidityBelowSafetyMargin (133) is raised. Skipped entirely when max_total_stake == 0 ("no cap"). Issue Web3Novalabs#1119 — multi-sig emergency cancellation: - New constant EMERGENCY_CANCEL_MULTISIG_THRESHOLD (2 distinct approvals). - New entry point `emergency_cancel_pool(approver, pool_id, reason)`. Admin/operator addresses each call once; the first call records the reason and proposer's approval, subsequent distinct calls add their approval. Once the threshold is reached the pool transitions to MarketState::Canceled via the same path as cancel_pool. Same-address re-approval is rejected with EmergencyCancelAlreadyApproved (135). Non-privileged callers are rejected with Unauthorized (10). - New DataKey variants EmergencyCancelApprovers(pool_id) and EmergencyCancelReason(pool_id), both cleared on execution. - New read-only `get_emergency_cancel_approvals(pool_id) -> Vec<Address>`. Baseline fix (required for any test build to succeed): - `mod events; pub use events::*;` re-exports event types into the lib module so usages like `ClaimWindowUpdateEvent` resolve. - Added missing `TimeConstraintError = 84` variant referenced in two existing call sites. These broke the lib test build on main; the baseline now compiles cleanly for both `cargo build --release --target wasm32-unknown-unknown` and `cargo test --lib`. Tests: - 13 new tests covering all four issues (3 for Web3Novalabs#1122, 3 for Web3Novalabs#1130, 3 for Web3Novalabs#1131, 4 for Web3Novalabs#1119). - 1 existing test (test_pool_end_time_at_leap_day_already_past) updated to expect the typed `Web3Novalabs#132` error instead of the legacy assert message — same behavior, stronger error reporting. Verification: - `cargo test -p predifi-contract --lib` → 386 passed, 0 failed. - `cargo build --release --target wasm32-unknown-unknown -p predifi-contract` → clean.
|
@Divine-designs is attempting to deploy a commit to the shola's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
@Divine-designs 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! 🚀 |
Yunusabdul38
approved these changes
Jun 30, 2026
Yunusabdul38
left a comment
Collaborator
There was a problem hiding this comment.
LGTM
Thanks for your contribution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four contract-safety / hardening enhancements in one PR, all touching
contracts/predifi-contract/.Issue #1122 — Validate outcome descriptions bounds on creation
MAX_OUTCOME_DESCRIPTION_LEN = 128andMIN_OUTCOME_DESCRIPTION_LEN = 1.validate_pool_invariantspanics on empty or oversized outcome labels.OutcomeDescriptionTooLong = 130,OutcomeDescriptionEmpty = 131.Issue #1130 — Validate staking deadlines are in the future
create_poolraisesPredifiError::DeadlineInPast = 132whenend_time < current_time(typed, machine-checkable) or when a non-zerostart_timeis strictly in the past.assert!(end_time > current_time, ...)is preserved as a boundary diagnostic forend_time == current_time.start_time == 0remains the "open immediately" sentinel.Issue #1131 — Add initial liquidity safety margin checks
INITIAL_LIQUIDITY_SAFETY_MARGIN_BPS = 100(1%).max_total_stake > 0,initial_liquiditymust be ≥max_total_stake * 1%; otherwiseInitialLiquidityBelowSafetyMargin = 133is raised. Skipped entirely whenmax_total_stake == 0(uncapped pool).Issue #1119 — Support multi-sig emergency cancellation
emergency_cancel_pool(approver, pool_id, reason)and read-onlyget_emergency_cancel_approvals(pool_id) -> Vec<Address>.EMERGENCY_CANCEL_MULTISIG_THRESHOLD = 2distinct admin/operator approvals. First approval records intent + reason; subsequent distinct approvals are added; once threshold is met the pool transitions toCanceledvia the same path ascancel_pool.EmergencyCancelAlreadyApproved = 135. Non-privileged caller →Unauthorized = 10.EmergencyCancelApprovers(pool_id)andEmergencyCancelReason(pool_id), both cleared on execution.Baseline-fix included
maindid not compile in test mode on entry:lib.rsreferencedClaimWindowUpdateEventwithout importing it (recently moved intoeventsmod).lib.rsreferencedPredifiError::TimeConstraintErrorwhich did not exist on the local enum.The PR re-exports
eventsinto the lib module (pub use events::*;) and adds the missingTimeConstraintError = 84variant so bothcargo build --release --target wasm32-unknown-unknownandcargo test --libnow succeed.Tests
test.rs, one block per issue:test_pool_end_time_at_leap_day_already_past) to expect the typed#132error instead of the legacy assert string.Verification
Closes #1119
Closes #1122
Closes #1130
Closes #1131