Skip zero-cost book fills when floor(fill × price) is 0 (#470) #1004
No reviewers
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!1004
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/470-match-zero-cost-skip"
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?
Summary
Fixes GitLab #470: when a resting limit price is below 1 token1 per token0, small fills can make
floor(fill × price) = 0whilefill > 0. Without a guard,match_asksdebited maker token0 escrow and credited 0 token1 (symmetric bug onmatch_bids).Change: after computing
cost(and the too-expensive shrink loop), skip the order whencost.is_zero()— same path insimulate_match_*and indexerdb_orderbook_simfor L8 parity.Documented as invariant L18 in
docs/contracts-security-audit.mdanddocs/limit-orders.md.Acceptance checklist
match_asksskips fill whenfloor(fill_t0 × price) = 0cd smartcontracts && cargo test -p cl8y-dex-tests match_asks_skips_zero_cost_fill_sub_unity_pricematch_bidssymmetric skipcd smartcontracts && cargo test -p cl8y-dex-tests match_bids_skips_zero_cost_fill_sub_unity_pricesimulate_match_*parity (L8)HybridSimulation.return_amount == 0; pairorderbook::unit testscd indexer && cargo test --lib db_orderbookcd smartcontracts && cargo test -p cl8y-dex-pair orderbook::docs/contracts-security-audit.mdL18,docs/limit-orders.md,skills/AGENTS_BOOK_MATCH_HINT_SECURITY.mdmatch_bids+simulate_match_bids+ indexersimulate_match_bidsall guardedThird-party verification
Manual repro (pre-fix): place ask at price 0.4, hybrid swap token1→token0 with
book_input=1; maker lost token0 with zero token1 payout. Post-fix: orderremainingunchanged.Related: #381 hardening umbrella. Issue #470 left open until merge.
Security review — MR !1004
Commit reviewed:
93a8b20096e86b18221e4c4837534ade76954d14Scope: L18 zero-cost fill skip in
match_bids/match_asks,simulate_match_*, indexerdb_orderbook_sim; docs/tests/skills only elsewhere.Outcome:
FINDINGS: 0medium+Summary
This MR closes a pre-existing maker fund-loss bug (GitLab #470): without the guard,
floor(fill × price) = 0withfill > 0debited maker escrow while crediting zero on the counter leg. The fix correctly skips the order (continue) after the shrink loop, beforemakers_usedincrement and any escrow/payout mutation — symmetric on bids and asks.Attack-path review (no new medium+ issues):
book_input/ hybrid split →match_*fill mathoffer_consumed = 0; unconsumedbook_legrolls to pool per existing hybrid routing (pool_input_amount = pool_leg + book_leg − offer_consumed)min_return,belief_price,max_spread) still apply at executedb_orderbook_simguarded same as on-chainsimulate_match_*MAX_SCAN_STEPSwithout fillingbook_start_hint,CleanLimitBook); attacker must post escrow; not introduced by this diffPrior security-review threads: none on this MR.
Inline findings: none (no medium+ items to thread).
Security review: no medium+ findings on this diff.