Skip to content

fix(v2): enforce MAX_ANTI_SNIPE_HARD_MAX_SECS upper bound on initialize - #116

Merged
collinsezedike merged 12 commits into
drydocs:mainfrom
Santia2004:fix/anti-snipe-upper-bound
Aug 27, 2026
Merged

fix(v2): enforce MAX_ANTI_SNIPE_HARD_MAX_SECS upper bound on initialize#116
collinsezedike merged 12 commits into
drydocs:mainfrom
Santia2004:fix/anti-snipe-upper-bound

Conversation

@Santia2004

Copy link
Copy Markdown
Contributor

Closes #114

Summary

  • Added MAX_ANTI_SNIPE_HARD_MAX_SECS constant (30 * 24 * 60 * 60, 30 days) to prevent setting an unbounded or excessively large anti_snipe_hard_max_secs at initialization that could lead to arithmetic overflow during dispute resolution.
  • Added upper bound validation check in initialize() for tholos-v2, returning Error::InvalidAntiSnipeParams if anti_snipe_hard_max_secs > MAX_ANTI_SNIPE_HARD_MAX_SECS.
  • Added unit tests in test.rs to verify rejection of values above MAX_ANTI_SNIPE_HARD_MAX_SECS as well as acceptance at the exact bound.

Test plan

  • Added test_initialize_rejects_anti_snipe_hard_max_over_max covering rejection of out-of-bound values.
  • Added test_initialize_accepts_anti_snipe_hard_max_at_max ensuring valid boundary values initialize cleanly.
  • Preserved all existing relative checks (anti_snipe_hard_max_secs >= registration_duration_secs and anti_snipe_extension_secs <= anti_snipe_hard_max_secs).

@collinsezedike collinsezedike left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

One thing outside this PR's diff, not blocking on its own but worth catching now: docs/src/CONTRACT_V2.md's InvalidAntiSnipeParams row and the initialize section only document the two existing relative-bound rejection rules. Please add a line for the new anti_snipe_hard_max_secs > MAX_ANTI_SNIPE_HARD_MAX_SECS case this PR introduces.

Comment thread contracts/tholos-v2/src/test.rs Outdated
let disputer = f.funded_address();
let voter = f.funded_address();
f.mint(&voter, DEFAULT_MINT);
f.mint(&voter, DEFAULTMINT);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Typo: DEFAULTMINT should be DEFAULT_MINT. This breaks compilation of the whole test suite, cargo check --tests fails with cannot find value DEFAULTMINT in this scope, so nothing in this crate can currently pass CI.

}

// ---------------------------------------------------------------------------
// Property-based tests for settlement's pro-rata forfeiture splitting and

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This PR strips 53 lines of explanatory doc comments from the proptest_settlement module (added in a prior merged PR) that have nothing to do with the anti-snipe fix here, looks like an accidental revert from branching off an older base or a merge conflict resolved the wrong way. Please restore them, they explain the rationale for run_scenario, expected_pool, is_recipient, and both proptest! cases.

@Santia2004

Copy link
Copy Markdown
Contributor Author

Hi @collinsezedike, thank you for the feedback!

  • Corrected the DEFAULTMINT typo in test.rs.
  • Restored the proptest doc comments.
  • Updated docs/src/CONTRACT_V2.md to document the MAX_ANTI_SNIPE_HARD_MAX_SECS rejection case.

@collinsezedike

Copy link
Copy Markdown
Collaborator

Hey @Santia2004, the DEFAULT_MINT typo fix is confirmed, compiles clean now. But the commit message says it also restores the proptest comments and updates the docs, neither of those actually happened in that commit, only the one-line typo fix went in. The other two findings from the last review (the 115 stripped doc-comment lines in proptest_settlement, and CONTRACT_V2.md's undocumented new error condition) are still outstanding. Can you push those separately?

@Santia2004

Copy link
Copy Markdown
Contributor Author

Hi @collinsyzedike, both items are now addressed in commit 8b3b488:

  • Restored the 115 stripped doc-comment lines in contracts/tholos-v2/src/test.rs (proptest settlement suite).
  • Updated docs/src/CONTRACT_V2.md to document the MAX_ANTI_SNIPE_HARD_MAX_SECS upper-bound rejection case under Error::InvalidAntiSnipeParams and the initialize() reference.

Thanks!

@collinsezedike collinsezedike left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Both items from the last round are confirmed fixed, the proptest comments are restored verbatim and the docs update is accurate. One new thing, subtle but real.

Comment thread contracts/tholos-v2/src/lib.rs Outdated

const MAX_REGISTRATION_DURATION_SECS: u64 = 7 * 24 * 60 * 60;
const MAX_REVEAL_DURATION_SECS: u64 = 7 * 24 * 60 * 60;
pub const MAX_ANTI_SNIPE_HARD_MAX_SECS: u64 = 30 * 24 * 60 * 60; // 30 days

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is set to exactly 30 days, the same as INSTANCE_BUMP_AMOUNT's persistent-storage TTL bump, zero margin. The comment right below this line says the bound "must leave real margin within the 30-day persistent-storage TTL bump ... for finalize to actually get called before the assertion's ledger entry risks archival", and this constant sits exactly at that edge rather than safely under it. An admin setting anti_snipe_hard_max_secs to the new max, with no intervening register() calls to bump TTL, risks the assertion's persistent entries being archived right around when resolve_outcome needs to read them. Worth trimming this below 30 days, e.g. 29 * 24 * 60 * 60, to actually satisfy the margin the comment describes.

@Santia2004

Copy link
Copy Markdown
Contributor Author

Hi @collinsyzedike, adjusted MAX_ANTI_SNIPE_HARD_MAX_SECS down to 29 days (29 * 24 * 60 * 60) in lib.rs and updated docs/src/CONTRACT_V2.md accordingly to leave the necessary margin against the 30-day persistent storage TTL bump.

Thanks!

@collinsezedike collinsezedike left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The 29-day trim is correct, compiles clean and actually leaves the margin the comment asks for. One leftover from that same fix.

Comment thread docs/src/CONTRACT_V2.md Outdated
| `InvalidRegistrationDuration` | `registration_duration_secs` is zero or exceeds 7 days. |
| `InvalidRevealDuration` | `reveal_duration_secs` is zero or exceeds 7 days. |
| `InvalidAntiSnipeParams` | `anti_snipe_extension_secs` exceeds `anti_snipe_hard_max_secs`, or `anti_snipe_hard_max_secs` is shorter than `registration_duration_secs`. |
| `InvalidAntiSnipeParams` | `anti_snipe_extension_secs` exceeds `anti_snipe_hard_max_secs`, `anti_snipe_hard_max_secs` is shorter than `registration_duration_secs`, or `anti_snipe_hard_max_secs` exceeds `MAX_ANTI_SNIPE_HARD_MAX_SECS` (30 days). |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Still says "(30 days)" here, but MAX_ANTI_SNIPE_HARD_MAX_SECS is now 29 days after this PR's own last commit. Please update this to match.

@Santia2004

Copy link
Copy Markdown
Contributor Author

Hi @collinsyzedike, updated the remaining (30 days) reference to (29 days) in the CONTRACT_V2.md error table as well.

Thanks!

@collinsezedike

Copy link
Copy Markdown
Collaborator

Hey @Santia2004, I don't see a new commit, the branch is still on 05a990f and line 178 still says "(30 days)". Did the push go through?

@Santia2004

Copy link
Copy Markdown
Contributor Author

Hi @collinszedike! The new commit (9e48cea) has been pushed and line 178 is now updated to reflect the 29 days upper bound. Could you please approve the workflow runs and take another look? Thanks

@collinsezedike

Copy link
Copy Markdown
Collaborator

Hey @Santia2004, cargo fmt --check is still failing, there's a trailing blank line at the very end of contracts/tholos-v2/src/test.rs (after the closing brace on the last function). Run cargo fmt locally and commit the result, that should clear it.

@Santia2004

Copy link
Copy Markdown
Contributor Author

Just pushed the fix in 27bde8e removing the extra trailing blank line at the end of the file. Thanks!

@collinsezedike collinsezedike left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

CI is green now and everything from the earlier rounds checks out. One thing outside this PR's diff, not blocking on its own but worth catching: docs/src/DEPLOYMENT_V2.md's anti_snipe_hard_max_secs guidance row (line 35) never mentions the new 29-day ceiling. Its own suggested sizing formula (registration_duration_secs + 100 * anti_snipe_extension_secs) can easily exceed 29 days with no warning. Please add a line there mentioning the contract-enforced cap, same as the sibling rows already do for their own bounds.

Comment thread contracts/tholos-v2/src/lib.rs Outdated

@collinsezedike collinsezedike left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the contribution @Santia2004, feel free to pick up another open issue.

@Santia2004

Copy link
Copy Markdown
Contributor Author

Thanks a lot for the patience and guidance throughout the reviews, @collinszedike! Looking forward to picking up the next one.

@collinsezedike
collinsezedike merged commit 4635b2c into drydocs:main Aug 27, 2026
4 checks passed
@collinsezedike

Copy link
Copy Markdown
Collaborator

Hey @Santia2004, nice work getting this one clean. If you're up for another, #94, #75, and #72 are all open and unassigned.

@Santia2004
Santia2004 deleted the fix/anti-snipe-upper-bound branch August 27, 2026 15:32
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.

[Bug] anti_snipe_hard_max_secs has no upper bound at initialize

2 participants