Contracts: Cap SetDiscountRegistryAll unbounded message fan-out (M3) #242
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:implement
agent:implement
agent:open_issues
agent:ready
agent:research
agent:security_audit
agent:verify
architecture
backend
blocker:hybrid
blocker:launch
blocker:limit-orders
blocker:v2
block:log_only
block:security
bug
ci
contracts
correctness
deploy
dev
devops
docs
documentation
duplicate
e2e
enhancement
epic
feature
frontend
functional-completion
gas
good first issue
governance
help wanted
high-risk
hooks
hybrid
indexer
infra
infrastructure
integrators
invalid
launch-blocker
limit-orders
localnet
localterra
low priority
missing-implementation
needs-design
ops
performance
priority
high
priority
medium
product
qa
QA
question
ready
ready
research
scripts
security
security-hardening
smartcontracts
tech-debt
testing
ux
UX
v2
verification
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-dex-terraclassic#242
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Reference
Gap analysis:
gaps/GAP_1780200149.md— finding M3.Current codebase
Factory governance can push fee-discount registry to all pairs via
SetDiscountRegistryAll(smartcontracts/contracts/factory/src/contract.rs:369-401):0..PAIR_COUNTVec<WasmMsg>viaadd_messagesA batched variant already exists:
SetDiscountRegistryBatch(lines 404+) withstart_after,limit, andcalc_limitgas bounding.As pair count grows, the "all" message exceeds block gas limits → governance tx fails (liveness/DoS for registry updates).
Why this is needed
Factory governance must reliably update discount registry across all pairs. Unbounded fan-out is a block-gas DoS that worsens linearly with pair count. Operators may be unable to rotate registry during incidents.
Constraints / guardrails
calc_limitused elsewhere in factory.SetDiscountRegistryon pair contract.Relevant files
smartcontracts/contracts/factory/src/contract.rsexecute_set_discount_registry_all, batch variantsmartcontracts/contracts/factory/src/msg.rssmartcontracts/tests/src/lib.rsdocs/reference/fee-discount-tiers.mdRecommended direction
Option A (preferred): Remove or cap
SetDiscountRegistryAllatcalc_limitpairs; return error if more remain — forceSetDiscountRegistryBatchloop.Option B: Implement internal pagination via reply pattern (heavier).
Update docs/scripts with batch loop example for governance multisig.
Acceptance criteria
Test plan — all paths
Run:
make test-contractsTest plan — attack / abuse vectors
Verification criteria
make test-contractsgreen.mentioned in commit
4daa4c69d5Implementation (merged to
main—4daa4c6)Capped factory
SetDiscountRegistryAllso a single governance tx cannot attach unbounded Wasm submessages (gap M3 / GAP_1780200149).On-chain behavior
PAIR_COUNTagainstcalc_limit(None)(default 10, same cap family asSetDiscountRegistryBatch).PAIR_COUNT > 10, returnsDiscountRegistryAllTooManyPairswith an error directing operators toSetDiscountRegistryBatch(start_after+limit).SetDiscountRegistryon the pair contract unchanged.Tests (
make test-contracts)test_set_discount_registry_all— still passes for small factories (≤10 pairs).test_set_discount_registry_all_rejects_when_pair_count_exceeds_cap— 11 pairs → error mentions batch API.test_set_discount_registry_batch_covers_many_pairs— 25 pairs,limit=10→ 3 txs, all pairs updated.Note:
limit_order_tests::place_limit_insert_steps_exceededstill fails onmainbefore this change (unrelated); all new/#242 tests pass.Docs / agent cross-links
skills/AGENTS_FEE_DISCOUNT_TIERS.md— rollout tableskills/AGENTS_TERRACLASSIC_GAS.md— rule 12docs/testing.md,gaps/GAP_1780200149.md(M3 marked fixed)Verification checklist
git pull&&make test-contracts— runset_discount_registry*tests; confirm 316 pass or note pre-existingplace_limit_insert_steps_exceededfailureset_discount_registry_allstill succeedsset_discount_registry_allfails withDiscountRegistryAllTooManyPairsset_discount_registry_batchuntilhas_more=false(usenext_start_afterfrom events)Unauthorizedon all/batch/single paths@brouie — please verify on your side when convenient; leaving this issue open until confirmed.
Verification complete (agent, worktree
verify/issue-242)Verified GitLab #242 / gap M3 on commit
c34630b(includes fix4daa4c6) using git worktree../cl8y-dex-terraclassic-verify-242.What was checked
On-chain behavior (
smartcontracts/contracts/factory/src/contract.rs)SetDiscountRegistryAllrejects whenPAIR_COUNT > calc_limit(None)(default 10) withDiscountRegistryAllTooManyPairs, directing operators toSetDiscountRegistryBatch.SetDiscountRegistryBatchemits bounded Wasm submessages withstart_after/limit/next_start_after/has_morepagination.SetDiscountRegistryunchanged.Tests (
make test-contracts— 316 integration tests, all green)test_set_discount_registry_all— ≤10 pairs, single-tx shortcut still workstest_set_discount_registry_all_rejects_when_pair_count_exceeds_cap— 11 pairs → error mentions batch APItest_set_discount_registry_batch_covers_many_pairs— 25 pairs,limit=10→ 3 txs, all pairs updatedtest_set_discount_registry_batch_paginates_cursor— cursor /next_start_after/has_moretest_factory_set_discount_registry_all_unauthorized+test_set_discount_registry_batch_unauthorized— non-governance rejectedmake check-fee-discount-tier-docs— OKDocs / agent cross-links (invariants documented)
skills/AGENTS_FEE_DISCOUNT_TIERS.md— rollout tableskills/AGENTS_TERRACLASSIC_GAS.md— rule 12docs/testing.md,gaps/GAP_1780200149.md(M3 marked fixed),smartcontracts/scripts/deploy.shbatch hintNo code changes required; fix already on
main. Infra not restarted.Acceptance criteria (issue body)
Test plan paths
limit=10, 25 pairs → 3 txs cover allSetDiscountRegistryAllover cap → error with batch continuation hintregistry: null) — same batch code path as set;Noneaccepted in batch handler (see unauthorized test); operationally identical to set rolloutUnauthorizedVerification checklist (for operators)
git pull origin main && make test-contractsmake check-fee-discount-tier-docsset_discount_registry_allfails and paginatedset_discount_registry_batchcompletes (has_more=false)set_discount_registry_allstill works in one txClosing — all issue-body and prior-comment verification criteria pass.
mentioned in issue #277
mentioned in issue #361
mentioned in issue #535