fix(contracts): material pool leg for no-belief hybrid max_spread (#307) #785
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!785
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "cursor/gitlab-issue-workflow-dc06"
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
Closes https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/307 (follow-up to #273).
When a hybrid swap routes to the limit book without belief_price, the declared pool_input must be at least 10% of offer_amount (minimum 1 raw unit) and the pool leg must produce non-zero net output before the #273 book-shortfall term runs. Pure-book hybrids (declared_pool_input = 0) are unchanged.
Acceptance checklist
Issue left open until merge.
mentioned in issue #307
changed the description
changed the description
Security review (automated)
Commit reviewed:
6cf3d7a4dd4fe2e25826578186103539e7b59651Scope: MR !785 diff vs
main(contractsmax_spread/ pair / router #307, factory #276/#277, indexer rate-limit #282 / limit clamps / resting-book mirror, frontend preflight, QA scripts). Prior MR discussions contained no security-review threads to re-validate.Outcome:
FINDINGS: 0medium+Inline threads: none
Summary
This MR closes the no-belief hybrid slippage bypass tracked in #307 (dust declared
pool_inputdestabilizing the #273 book-shortfall reference). Changes are defensive and align on-chain checks, router prechecks, frontend preflight, and audit invariant L9.Contract path (#307 / L9) — reviewed, no new bypass
validate_declared_hybrid_pool_leg_for_no_beliefin pairexecute_swapand routervalidate_hybrid_declared_split_for_no_beliefwhenbelief_priceis unset and bothpool_inputandbook_inputare non-zero.check_max_spreadusesdeclared_pool_inputfor the 10% floor and requirespool_net_return > 0before applying the #273 book-shortfall term.pool_input,book_input,max_spread, book fills) are bounded by existing L4 split equality, L5 scan/maker caps, and the updated spread math; integration tests (hybrid_no_belief_dust_pool_leg_rejected,hybrid_no_belief_book_far_below_pool_rejected) cover the PoC shapes.declared_pool_input = 0) remain outside the #273/#307 no-belief metric; unfilled book remainder may still hit the pool. Documented inmax_spread.rs, L9, and tests (pure_book_hybrid_skips_material_pool_floor). Users must rely onbelief_price/ routerminimum_receive— pre-existing product boundary, not a regression in this diff.Other security-relevant diff hunks
CreatePairuluna refund when fee = 0)SetLpAdminfromUpdateConfig; boundedSetLpAdminAll/SetLpAdminBatch)/64rate-limit keys viaConnectInfo, noX-Forwarded-For)LIMITSQL errors (availability), not authz.resting_ordersSQLORDER BYprice_dirderived only from internal"bid"/"ask"— no caller-controlled SQL injection.Not reported (per policy)
belief_priceslippage models unrelated to the #307 fix.Security review: no medium+ findings on this diff.
Stale Security Review comment
Stale Security Review comment
Stale Security Review comment
Stale Security Review comment
Stale Security Review comment
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Reviewed by Cursor Bugbot for commit
6cf3d7a4dd. Configure here.Preflight shortfall ignores empty book
Medium Severity
hybridSpreadCmpAndTotalfolds in #273 book shortfall whenever declaredpool_inputandbook_inputare both positive, but on-chaincheck_max_spreadonly applies that term when the book actually consumed offer (book_input/book_returnnon-zero). A hybrid with a declared book leg that simulates to zero book output can pass execute yet fail route preflight spread gating.Additional Locations (1)
frontend-dapp/src/services/terraclassic/swapRoutePreflight.ts#L62-L65Reviewed by Cursor Bugbot for commit
6cf3d7a4dd. Configure here.added 1 commit
9ac09ab1- fix: skip book shortfall in preflight when book leg fills nothingCompare with previous version
changed the description
resolved all threads
Stale Security Review comment
Stale Security Review comment
Stale Security Review comment
Stale Security Review comment
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Reviewed by Cursor Bugbot for commit
9ac09ab1c1. Configure here.Hybrid sim skips pool leg
Medium Severity
HybridSimulationstill quotes dust-pool hybrids after execute began rejecting them viavalidate_declared_hybrid_pool_leg_for_no_beliefwhenbelief_priceis unset. Router simulation was updated, but the pair forward sim path was not, so LCD quotes and indexer grid search can overstate output for splits that fail on submit.Reviewed by Cursor Bugbot for commit
9ac09ab1c1. Configure here.Security review (automated)
Commit reviewed:
9ac09ab1c178c6c808b27eb60241189c84df642dScope: MR !785 diff vs
main—dex_common::max_spread(#273 book shortfall, #307 material pool leg), pairexecute_swap/assert_max_spread, router declared-split precheck +SimulateSwapOperations, frontendswapMaxSpread/ route preflight, audit doc L9, integration tests.Outcome:
FINDINGS: 0medium+Inline threads: none
Re-validation of prior threads
6cf3d7a):FINDINGS: 0— still holds on the updated head; no new bypass identified.offer_consumed_by_book. Fixed in9ac09ab(bookNet > 0ninhybridSpreadCmpAndTotal); contract parity confirmed atmax_spread.rs(book_input.is_zero()uses realized consumption). This was a preflight false-positive (UX), not an on-chain slippage bypass — no open medium+ item.Contract path (#307 / L9) — reviewed, no exploitable bypass
validate_declared_hybrid_pool_leg_for_no_beliefin pairexecute_swap(nobelief_price) and routervalidate_hybrid_declared_split_for_no_beliefpool_input,book_inputpool_input < 10%of offer (min 1 raw unit)check_max_spreadondeclared_pool_input+pool_net_returnInsufficientPoolLegForBookHybrid/ZeroPoolNetForBookHybridbefore #273 shortfallbook_shortfallusing realizedpool_input/book_inputhybrid_no_belief_book_far_below_pool_rejected)Intentional residual (documented, pre-existing): pure-book hybrids (
declared_pool_input = 0) skip #307/#273 no-belief metrics; unfilled book remainder may roll to the pool. Documented in L9,pure_book_hybrid_skips_material_pool_floor, and skill docs. Mitigation remainsbelief_price/ routerminimum_receive— product boundary, not a regression in this diff.Frontend / preflight
9ac09abaligns #273 shortfall gating with realized book output.humanizeTerraTxErroradditions are static copy only (no XSS / injection surface).Verification run on review VM
cargo test -p dex-common max_spread— passcargo test -p cl8y-dex-tests hybrid_no_belief— passnpm test -- src/utils/swapMaxSpread.test.ts— passSecurity review: no medium+ findings on this diff.
added 1 commit
365e61fb- fix(pair): reject dust pool leg in HybridSimulation quotesCompare with previous version
changed the description
Security review (automated)
Commit reviewed:
365e61fbe566b36b6923b199657d40c21243dd27Scope: MR !785 diff vs
main—dex_common::max_spread(#273 book shortfall, #307 material pool leg), pairexecute_swap/assert_max_spread/simulate_hybrid_swap_with_fee, router declared-split precheck +SimulateSwapOperations, frontendswapMaxSpread/ route preflight / tx error humanization, audit doc L9, integration tests.Outcome:
FINDINGS: 0medium+Inline threads: none
Re-validation of prior threads
9ac09ab):FINDINGS: 0— still holds on updated head.offer_consumed_by_book. Fixed in9ac09ab(bookNet > 0ninhybridSpreadCmpAndTotal). Preflight false-positive only (UX), not an on-chain slippage bypass — no open medium+ item.HybridSimulationquoted dust-pool hybrids after execute began rejecting them. Fixed in365e61fby mirroringvalidate_declared_hybrid_pool_leg_for_no_beliefinsimulate_hybrid_swap_with_fee(paircontract.rs~L2145). Sim/execute parity restored for the #307 declared-split floor; quote inflation for reject-on-submit splits is closed.Contract path (#307 / L9) — reviewed, no exploitable bypass
validate_declared_hybrid_pool_leg_for_no_beliefin pairexecute_swap(nobelief_price) and routervalidate_hybrid_declared_split_for_no_beliefpool_input,book_inputpool_input < 10%of offer (min 1 raw unit)simulate_hybrid_swap_with_fee(same validator)check_max_spreadviadeclared_pool_inputpool_net_return > 0before #273 book-shortfall termcheck_max_spreadno-belief branchpool_input,book_input, fillsdeclared_pool_input = 0) unchanged by design (belief / min_receive)Attacker-controlled swap params remain bounded by L4 split equality, L5 scan/maker caps, and the updated spread math. Integration tests (
hybrid_no_belief_dust_pool_leg_rejected,hybrid_no_belief_book_far_below_pool_rejected,hybrid_max_spread_exact_tolerance_succeeds) cover PoC shapes.Frontend — reviewed, no authz / injection surface
swapMaxSpread.ts/swapRoutePreflight.tsmirror on-chain guards; preflight may block more aggressively than chain (conservative).humanizeTerraTxError.tsmaps new revert strings to static copy (no HTML injection).Security review: no medium+ findings on this diff.
Stale Security Review comment
Stale Security Review comment
Stale Security Review comment
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Reviewed by Cursor Bugbot for commit
365e61fbe5. Configure here.Hybrid sim ignores belief bypass
Medium Severity
HybridSimulationalways runs the no-belief material pool-leg check, whileexecute_swapskips that validation whenbelief_priceis set. A hybrid with a sub-10% declaredpool_inputand a book leg can execute on-chain butHybridSimulation/ reverse sim queries error, breaking quote parity for belief-guarded swaps.Additional Locations (1)
smartcontracts/contracts/pair/src/contract.rs#L840-L861Reviewed by Cursor Bugbot for commit
365e61fbe5. Configure here.changed this line in version 4 of the diff
added 1 commit
f51bf936- fix(pair): skip no-belief pool-leg guard in hybrid sim when belief_price is setCompare with previous version
changed the description
Stale Security Review comment
Stale Security Review comment
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Reviewed by Cursor Bugbot for commit
f51bf9364e. Configure here.Frontend book shortfall misaligned
Medium Severity
Route preflight folds in #273 book shortfall using declared
pool_inputandbook_input, and only when simulatedbook_return_amountis positive. On-chaincheck_max_spreaduses realized pool offer (pool_legplus unfilled book) and offer actually consumed by the book, and still adds shortfall when book net is zero. Preflight can understate spread and allow submit when the pair rejects onmax_spread.Additional Locations (1)
frontend-dapp/src/services/terraclassic/swapRoutePreflight.ts#L62-L65Reviewed by Cursor Bugbot for commit
f51bf9364e. Configure here.Security review (automated)
Commit reviewed:
f51bf9364ee5a6b95425c806af759edb5fabb43dScope: MR !785 diff vs
main—dex_common::max_spread(#273 book shortfall, #307 material pool leg), pairexecute_swap/assert_max_spread/simulate_hybrid_swap_with_fee(incl. optional querybelief_price), router declared-split precheck +SimulateSwapOperations, frontendswapMaxSpread/ route preflight, factory #276/#277, indexer IPv6 rate-limit #282, audit doc L9, integration tests.Outcome:
FINDINGS: 0medium+Inline threads: none (new). Prior Bugbot threads on this MR are resolved on this SHA — see re-validation below.
Re-validation of prior threads
f51bf93book_inputwhen sim returned zero book nethybridSpreadCmpAndTotalgates shortfall onbookNet > 0n(9ac09ab).HybridSimulationquoted dust-pool hybrids rejected by executevalidate_declared_hybrid_pool_leg_for_no_beliefinsimulate_hybrid_swap_with_feewhenbelief_priceis unset (365e61f).belief_priceskips #307 guardbelief_priceand mirrors execute skip (f51bf93).Contract path (#307 / L9)
validate_declared_hybrid_pool_leg_for_no_beliefin pairexecute_swapand routervalidate_hybrid_declared_split_for_no_belief.check_max_spreadenforcesdeclared_pool_input ≥ 10%of offer (min 1 unit) andpool_net > 0before #273 book-shortfall; uses realizedpool_input/offer_consumed_by_bookfor the shortfall ratio.pool_input,book_input,max_spread, book fills) remain bounded by L4 split equality, L5 scan/maker caps, and updated spread math; PoC shapes covered byhybrid_no_belief_dust_pool_leg_rejectedandhybrid_no_belief_book_far_below_pool_rejected.declared_pool_input = 0) stay outside #273/#307 no-belief metric; takers must usebelief_price/minimum_receive. Pre-existing product boundary per L9.Other security-relevant hunks
belief_priceonHybridSimulation/ reverse simSetLpAdminAll/ batch; decouple fromUpdateConfig)Security review: no medium+ findings on this diff.
added 1 commit
Compare with previous version
changed the description
Stale Security Review comment
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Reviewed by Cursor Bugbot for commit c1f6903039cb226a7550f4397637e7c99ac4e6ac. Configure here.
Preflight miscomputes hybrid book legs
Medium Severity
hybridMaxSpreadRealizedLegsdoes not match pairassert_max_spread, which uses realizedoffer_consumed_by_bookandpool_leg + (book_leg − consumed)for #273. When the book only partially fills, preflight can omit book shortfall or use the wrong ratio, so route spread preflight may disagree with on-chainmax_spread.Additional Locations (1)
frontend-dapp/src/services/terraclassic/swapRoutePreflight.ts#L64-L67Reviewed by Cursor Bugbot for commit c1f6903039cb226a7550f4397637e7c99ac4e6ac. Configure here.
Security review (automated)
Commit reviewed:
c1f6903039cb226a7550f4397637e7c99ac4e6acScope: MR !785 diff vs
main—dex_common::max_spread(#273 book shortfall, #307 material pool leg), pairexecute_swap/assert_max_spread/HybridSimulation(optionalbelief_price), router declared-split precheck +SimulateSwapOperations, frontendswapMaxSpread/ route preflight, audit doc L9, integration tests.Outcome:
FINDINGS: 0medium+Inline threads: none
Re-validation of prior threads
c1f69037e14db6d)9ac09ab; superseded by realized-leg alignment inc1f6903(hybridMaxSpreadRealizedLegs)HybridSimulationskipped dust-pool guard (Bugbotc8571e37)365e61fHybridSimulationignoredbelief_pricebypass (Bugbota79c19cc)f51bf93767b1804)c1f6903— preflight now mirrors on-chain realizedpool_input/book_input, including zero book net with unfilled remainderNo remaining exploitable path identified on the latest head.
Contract path (#307 / L9) — reviewed, no bypass
validate_declared_hybrid_pool_leg_for_no_beliefin pairexecute_swap(whenbelief_priceunset) and routervalidate_hybrid_declared_split_for_no_beliefon swap start and each hop reply.check_max_spreadenforces declared pool ≥10% of offer (min 1 unit) and non-zeropool_net_returnbefore #273 book shortfall; maps toInsufficientPoolLegForHybrid/ZeroPoolNetForHybrid.pool_input,book_input,max_spread, book fills) remain bounded by L4 split equality, L5 scan/maker caps, and the updated spread math. Integration testshybrid_no_belief_dust_pool_leg_rejectedandhybrid_no_belief_book_far_below_pool_rejectedpass on this SHA.declared_pool_input = 0) remain outside the #273/#307 no-belief metric; unfilled book remainder may still hit the pool. Documented inmax_spread.rs, audit L9, andpure_book_hybrid_skips_material_pool_floor. Users must rely onbelief_price/ routerminimum_receive— pre-existing product boundary.Frontend / quote parity
swapRoutePreflight.ts) applies #307 material-pool guards and #273 shortfall viahybridMaxSpreadRealizedLegs, aligned with pairassert_max_spreadinputs afterc1f6903.HybridSimulation/ reverse sim honor optionalbelief_pricefor the material-pool guard, matching execute.Not reported (per policy)
Governance-trusted operations, stylistic issues, pre-existing pure-book / optional-
belief_priceslippage model, and indexer route-solver paths outside this diff.Security review: no medium+ findings on this diff.
added 1 commit
e1ae0596- fix(frontend): align hybrid max-spread preflight with on-chain #273 legsCompare with previous version
changed the description
Security review (automated)
Commit reviewed:
e1ae059653f509cf6682b3f23101cf6f1e0da4d7Scope: MR !785 diff vs
main—dex_common::max_spread(#273 book shortfall, #307 material pool leg), pairexecute_swap/assert_max_spread/HybridSimulation(optional querybelief_price,limit_book_offer_consumed), router declared-split precheck +SimulateSwapOperations, frontendswapMaxSpread/swapRoutePreflight, audit doc L9, integration tests. Re-checked prior automated/Bugbot threads on this MR.Outcome:
FINDINGS: 0medium+Inline threads: none
Re-validation of prior threads
e1ae059belief_pricebypasssimulate_hybrid_swap_with_fee/HybridSimulationquery accept optionalbelief_priceand skipvalidate_declared_hybrid_pool_leg_for_no_beliefwhen set (parity withexecute_swap).hybridMaxSpreadRealizedLegs+limit_book_offer_consumedfrom hybrid sim; preflight uses realized legs for #273; book shortfall whenbook_net = 0covered in unit tests.swapRoutePreflight.tsreadslimit_book_offer_consumed; fallback to declaredbook_inputonly when sim omits the field and book output is non-zero (errs strict vs chain).Contract path (#307 / L9) — no exploitable bypass found
validate_declared_hybrid_pool_leg_for_no_beliefon pairexecute_swapand routervalidate_hybrid_declared_split_for_no_beliefwhenbelief_priceis unset and bothpool_inputandbook_inputare non-zero.check_max_spreadenforces declared 10% pool floor,pool_net_return > 0, then #273 book shortfall using realizedpool_input(pool_leg + book_leg − offer_consumed_by_book) andoffer_consumed_by_book.pool_input + book_input == amount), L5 scan/maker caps, and spread math; integration testshybrid_no_belief_dust_pool_leg_rejectedandhybrid_no_belief_book_far_below_pool_rejectedmatch the historical PoC shapes.declared_pool_input = 0) are outside the #273/#307 no-belief metric; unfilled book remainder may still route to the pool. Mitigation remainsbelief_price/ routerminimum_receive— see L9 indocs/contracts-security-audit.md.Frontend / indexer
assert_max_spread./64rate-limit keying (#282) and limit clamps are hardening, not new attack surface.Other diff hunks (factory #276/#277, broadcast scope, QA scripts)
Security review: no medium+ findings on this diff.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.
Reviewed by Cursor Bugbot for commit
e1ae059653. Configure here.Preflight throws on dust pool
Medium Severity
When
hybridNoBeliefMaterialPoolRejectflags an insufficient declared pool leg, preflight still callssimulateHybridSwap, which now rejects the same split on-chain. The thrown LCD error abortspreflightSwapRouteSpreadinstead of returninganyHopExceedsMaxSpread: true, so slippage gating and quote flows that expect a structured preflight result break for invalid hybrid routes.Reviewed by Cursor Bugbot for commit
e1ae059653. Configure here.added 1 commit
72dcd562- fix: skip hybrid simulation when declared pool leg is dustCompare with previous version
changed the description
Security review (automated)
Commit reviewed:
72dcd5625011f188387e5a329270221cc8d69a2aScope: MR !785 diff vs
main—dex_common::max_spread(#273 book shortfall, #307 material pool leg), pairexecute_swap/assert_max_spread/HybridSimulation(optional querybelief_price,limit_book_offer_consumed), router declared-split precheck +SimulateSwapOperations, frontendswapMaxSpread/swapRoutePreflight, audit doc L9, integration tests.Outcome:
FINDINGS: 0medium+Inline threads: none
Re-validation of prior threads
72dcd567e14db6d)hybridMaxSpreadRealizedLegs+limit_book_offer_consumedHybridSimulationquoted dust-pool hybrids rejected by execute (Bugbotc8571e37)validate_declared_hybrid_pool_leg_for_no_beliefon sim pathbelief_priceskips #307 guard (Bugbota79c19cc)belief_pricemirrors execute skip767b1804,ccd0d5c2)pool_input/offer_consumed_by_book5d1ac711)72dcd56— earlybreakbeforesimulateHybridSwapwheninsufficient_pool_legNo remaining exploitable on-chain path identified on this head.
Contract path (#307 / L9) — reviewed, no bypass
validate_declared_hybrid_pool_leg_for_no_beliefin pairexecute_swapand routervalidate_hybrid_declared_split_for_no_beliefwhen bothpool_inputandbook_inputare non-zero.check_max_spreadenforces declared 10% pool floor andpool_net_return > 0before #273 book shortfall; uses realizedpool_input(pool_leg + book_leg − offer_consumed_by_book) andoffer_consumed_by_book.pool_input,book_input,max_spread, book fills) remain bounded by L4 split equality, L5 scan/maker caps, and updated spread math. Integration testshybrid_no_belief_dust_pool_leg_rejectedandhybrid_no_belief_book_far_below_pool_rejectedpass on this SHA.declared_pool_input = 0) stay outside the #273/#307 no-belief metric; unfilled book remainder may still route to the pool. Mitigation remainsbelief_price/ routerminimum_receive— see L9 indocs/contracts-security-audit.md.Frontend / preflight
Verification run on review VM
cargo test -p dex-common max_spread— passcargo test -p cl8y-dex-tests hybrid_no_belief— passSecurity review: no medium+ findings on this diff.
resolved all threads
mentioned in commit
27e7a61846