Repository navigation
fix(tholos-v2): bound max_total_weight/max_position ratio to raise Sybil cost (closes #168) - #215
Conversation
…bil cost - Enforces max_total_weight <= max_position * MAX_TOTAL_WEIGHT_TO_POSITION_RATIO (10) in initialize() - Adds Error::InvalidWeightRatio = 37 - Updates test_register_exceeds_max_position_fails and adds ratio bound unit tests - Updates docs/src/V2_BOND_SIZING.md profile rows and max_total_weight guidance - Updates scripts/testnet-load-v2.sh to use 10x ratio bound (100,000,000) - Documents InvalidWeightRatio and residual plutocratic risk in docs/src/CONTRACT_V2.md Closes #168
collinsezedike
left a comment
There was a problem hiding this comment.
@Ranjeet2063 A few things need attention before this can merge.
docs/src/DEPLOYMENT_V2.md's max_position/max_total_weight guidance was not updated for the new ratio bound. It still says max_position must be "at least 1 and at most max_total_weight" with no mention of the new 10x floor, and it suggests setting max_position to "perhaps 10-20% of max_total_weight", but 10% is exactly the new legal boundary and anything below it (which the phrasing invites) now reverts with InvalidWeightRatio. Update that table to state the new constraint.
docs/src/V2_BOND_SIZING.md's max_total_weight formula, m >= max(10, N_voters x k + 2), is now mathematically incompatible with the new m <= 10k ceiling for any deployment with more than about 9 full-max_position voters (N_voters x k + 2 <= 10k forces N_voters <= 10 - 2/k). The doc text mentions the new ratio bound in passing but doesn't reconcile it with the formula it sits next to, so a deployer following the documented formula for a larger committee will produce parameters this contract now rejects.
No docs/src/CHANGELOG.md entry for a new public error variant and a new initialize validation rule. The repo's convention for a v2 behavior change is a Fixed entry ending in Closes #168 (see the maintainer's own dd8c043 for the pattern).
Issue #168 explicitly asked for a short written ratio analysis to be confirmed with the maintainer before implementation, since this is a design trade-off rather than a pure bug fix. That didn't happen here, and it matters concretely: the two profile rows in V2_BOND_SIZING.md were brought into compliance by shrinking max_total_weight (100x to 50x base_bond, 200x to 30x base_bond) rather than raising max_position, which lowers the mainnet profile's ceiling on legitimate honest counter-stake from roughly 198x to roughly 28x base_bond. That may well be the right call, but it's a real trade-off this issue asked to be surfaced and agreed on explicitly, not decided implicitly by which side of the inequality got adjusted to pass the new check.
…elog for 10x ratio bound - Updates docs/src/DEPLOYMENT_V2.md max_position/max_total_weight guidance documenting 10x floor and 10% legal boundary - Reconciles docs/src/V2_BOND_SIZING.md capacity formula m >= max(10, N_voters * k_avg + 2) with m <= 10k ceiling - Documents single-whale resistance vs counter-stake liquidity trade-offs in narrative guidance - Adds docs/src/CHANGELOG.md Fixed entry for Error::InvalidWeightRatio ending in Closes #168
|
@collinsezedike Thank you for the thorough and constructive review! All points have been addressed in commit 1.
|
collinsezedike
left a comment
There was a problem hiding this comment.
@Ranjeet2063 All four points are resolved. DEPLOYMENT_V2.md now states the 10x floor and the 10% boundary correctly, V2_BOND_SIZING.md's formula reconciliation for larger committees (average-stake sizing) is mathematically sound, the CHANGELOG entry follows the repo's convention and closes #168, and the trade-off write-up on the ratio choice is clear and reasonable. The conservative profile choice for the mainnet row is a defensible default given that document's stated threat model, with the scale-up path for higher counter-stake ceilings now documented alongside it.
Thanks for the contribution. Feel free to pick up another open issue.
|
Hi @collinsezedike, thank you again for reviewing and approving this PR! All 124 tests are passing green ( |
|
@Ranjeet2063 If you found this useful, a star on the repo goes a long way. |
|
Hi @collinsezedike, just starred the repository! ⭐ Really enjoyed working on the Tholos V2 architecture, mathematical models, and Sybil resistance ratio bounds. If the Tholos / Drydocs team has upcoming roadmap milestones, Soroban smart contract security sprints, or is looking for a dedicated remote Rust/Soroban engineer for part-time or full-time contract roles, I would love to collaborate. Feel free to connect directly anytime:
|
|
Hey @Ranjeet2063, thank you for the contribution, and thank you for the star on the repo. |
Closes #168
Summary
Enforces
max_total_weight <= max_position * MAX_TOTAL_WEIGHT_TO_POSITION_RATIO(ratio = 10) atinitializetime. 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.Findings Addressed from Maintainer Review
docs/src/V2_BOND_SIZING.mdProfile Rows:Public testnet / low valueprofile row (max_position = 5x base_bond,max_total_weight = 50x base_bond, exactly 10x ratio).Higher-value mainnet candidateprofile row (max_position = 3x base_bond,max_total_weight = 30x base_bond, exactly 10x ratio).max_total_weightsizing guidance.scripts/testnet-load-v2.sh:MAX_TOTAL_WEIGHT=100000000(10xMAX_POSITION=10000000), ensuring the testnet load script passes contract initialization.max_position <= max_total_weight <= MAX_SETTLEMENT_TOTAL_WEIGHT(10^19), the productmax_position * MAX_TOTAL_WEIGHT_TO_POSITION_RATIOcannot overflowi128. Clean check without unreachable branch logic.Changes
contracts/tholos-v2/src/lib.rs:Error::InvalidWeightRatio = 37with doc comments.MAX_TOTAL_WEIGHT_TO_POSITION_RATIO: i128 = 10constant.initialize().contracts/tholos-v2/src/test.rs:test_initialize_accepts_max_total_weight_at_ratio_bound(at exact 10x bound, passes).test_initialize_rejects_max_total_weight_above_ratio_bound(one over bound, rejects withInvalidWeightRatio).test_register_exceeds_max_position_failsto satisfy the 10x ratio invariant.docs/src/CONTRACT_V2.md:max_total_weightratio bound in parameter table.InvalidWeightRatioto error table.get_policy.Verification
cargo test -p tholos-v2: 124 passed, 0 failed.cargo clippy -p tholos-v2 --all-targets: Clean, 0 warnings.cargo fmt --check: Clean formatting verified.