Skip to content

fix(tholos-v2): bound max_total_weight/max_position ratio to raise Sybil cost - #182

Open
devkryssie wants to merge 1 commit into
drydocs:mainfrom
devkryssie:fix/issue-168-weight-ratio-bound
Open

fix(tholos-v2): bound max_total_weight/max_position ratio to raise Sybil cost#182
devkryssie wants to merge 1 commit into
drydocs:mainfrom
devkryssie:fix/issue-168-weight-ratio-bound

Conversation

@devkryssie

Copy link
Copy Markdown

Closes #168

What

Enforces max_total_weight <= max_position * MAX_TOTAL_WEIGHT_TO_POSITION_RATIO (ratio = 10) at initialize time. A single actor must now control at least 10 distinct positions to approach the eligible-total threshold, raising the capital cost of Sybil-style address splitting without requiring an external identity system.

Changes

  • contracts/tholos-v2/src/lib.rs

    • Adds Error::InvalidWeightRatio = 37 with a doc comment.
    • Adds MAX_TOTAL_WEIGHT_TO_POSITION_RATIO: i128 = 10 constant after MAX_SETTLEMENT_TOTAL_WEIGHT.
    • Validates the ratio in initialize() immediately after the existing max_position check, using checked_mul so a pathologically large max_position can't overflow the product.
  • contracts/tholos-v2/src/test.rs

    • test_initialize_accepts_max_total_weight_at_ratio_bound: max_total_weight = 10_000, max_position = 1_000 (exactly at bound) — must succeed.
    • test_initialize_rejects_max_total_weight_above_ratio_bound: max_total_weight = 10_001, max_position = 1_000 (one over) — must return InvalidWeightRatio.
    • test_register_exceeds_max_position_fails: updated max_total_weight from DEFAULT_MAX_TOTAL_WEIGHT to (DEFAULT_BOND + 50) * 10 so it satisfies the new ratio invariant.
  • docs/src/CONTRACT_V2.md

    • max_total_weight field description now documents the ratio bound.
    • InvalidWeightRatio added to the error table.
    • Residual plutocratic risk note added before get_policy: the ratio raises splitting cost but a coalition controlling >50% of eligible capital can still determine the result.

Testing

cargo test -p tholos-v2 — 112 passed, 0 failed.

…bil cost (drydocs#168)

Enforces a maximum ratio of max_total_weight to max_position
(MAX_TOTAL_WEIGHT_TO_POSITION_RATIO = 10) at initialize time, so a
single actor must control at least 10 distinct positions to approach the
plutocratic threshold, raising the capital cost of address splitting.

- Adds Error::InvalidWeightRatio (= 37).
- Adds MAX_TOTAL_WEIGHT_TO_POSITION_RATIO = 10 constant with doc comment.
- Validates the ratio in initialize() after the max_position check.
- Adds two tests: accept at the exact bound (10_000 / 1_000 = 10) and
  reject one unit above it (10_001 / 1_000).
- Fixes test_register_exceeds_max_position_fails to pass
  (DEFAULT_BOND + 50) * 10 for max_total_weight so it satisfies the
  new ratio invariant.
- Updates docs/src/CONTRACT_V2.md with the new invariant, the
  InvalidWeightRatio error, and an explicit residual plutocratic risk
  note.

Closes drydocs#168
.checked_mul(MAX_TOTAL_WEIGHT_TO_POSITION_RATIO)
.unwrap_or(i128::MAX);
if max_total_weight > max_allowed_total {
return Err(Error::InvalidWeightRatio);

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 directly conflicts with docs/src/V2_BOND_SIZING.md's own published profile table, which isn't touched by this PR. Public testnet / low value (max_position 5x, max_total_weight 100x, ratio 20) and Higher-value mainnet candidate (3x, 200x, ratio 66.7) both now revert with InvalidWeightRatio if anyone actually follows that guidance. Only Private beta (10x, 50x, ratio 5) survives. Please update that table's max_position/max_total_weight columns for the other two profiles to fit within the new ratio 10 cap, or adjust the cap if 20x/66x should remain valid.

@collinsezedike

Copy link
Copy Markdown
Collaborator

@devkryssie Three things.

  1. docs/src/V2_BOND_SIZING.md's Public testnet and Higher-value mainnet profile rows recommend ratios of 20x and 66.7x, both now over this PR's new 10x cap. initialize would revert for either documented profile. Please update those rows to fit the new cap.
  2. scripts/testnet-load-v2.sh's max_position/max_total_weight give a ratio of 100, also over the cap. The load test script will fail outright until it's updated.
  3. The checked_mul overflow guard on max_position * MAX_TOTAL_WEIGHT_TO_POSITION_RATIO is dead code given the validation that already runs earlier in the function. The comment describes it protecting against a case that can't actually be reached.

@collinsezedike

Copy link
Copy Markdown
Collaborator

@devkryssie Checking in, any progress on the findings above? Let us know if you're still working it or need to hand it off.

@collinsezedike

Copy link
Copy Markdown
Collaborator

@devkryssie Second check-in, still no word since the findings or the first ping. Please let us know if you're still working this or need to hand it off.

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] register() has no Sybil resistance in tholos-v2

2 participants