Repository navigation
feat(lunarbase): support v0.4.1 pools and BSC indexing - #1445
ThomasAqu1nas wants to merge 4 commits into
Conversation
Update punishment math, indexed state, and caller-dependent fees while preserving oracle freshness across blocks and consecutive swaps. Add verified Base/BSC bootstrap snapshots and BSC test-harness wiring.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
| ) -> tycho::ProtocolComponent { | ||
| tycho::ProtocolComponent::new(&component_id(pool)) | ||
| .with_tokens(&[token_x, token_y]) | ||
| .with_attributes(&[("quote_caller", quote_caller)]) |
There was a problem hiding this comment.
What does quote_caller do? Can we just assume the Tycho Router fee is zero?
There was a problem hiding this comment.
I'd suggest removing quote_caller in the substreams and quote_caller_whitelisted in the simulation. We can just assume the Tycho router is whitelisted. Otherwise, if we ever change the router, we'd have to update the substreams and do a full resync, which is a lot of extra work.
…g in bootstrap process
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the PropellerHeads CLA and I hereby sign the CLA |
| Direction::XToY => (q96, anchor), | ||
| Direction::YToX => (anchor, q96), | ||
| }; | ||
| let probe = (BigUint::from(reserve_out) * &numerator / &denominator) * numerator / denominator; |
There was a problem hiding this comment.
The empty-input-reserve probe can report zero limits for a tradable direction because these two divisions round down, while quote_limit only reduces the input after a rejected quote.
I reproduced this with a fresh, unpaused pool, zero fees and punishment, reserve_x = 0, reserve_y = 1, and anchor_price_x96 = 3 * Q96 / 4. For X -> Y:
- This probe evaluates to
floor(floor(1 / 0.75) / 0.75) = 1. - Quoting input 1 produces zero output, so
quote_limithalves the input to zero and returns(0, 0). - However, input 3 is valid: the actual quote is
floor(floor(3 * 0.75) * 0.75) = 1, andquote_exact_in(3)succeeds.
A temporary regression test confirmed that the direct quote succeeds while get_limits returns (0, 0). Consumers relying on these limits will skip this tradable direction.
Could we derive the probe from the quote's exact rounding rules, or distinguish an input that is too small to produce output from an input that exceeds the available liquidity, rather than halving both cases?
There was a problem hiding this comment.
[P2] Reconfirmed on b68828334: this also affects the reverse direction and small nonzero input reserves.
A temporary regression test exercised fresh, unpaused states with zero fees and punishment, output reserve = 1, and these four cases:
| Direction | Anchor | Input reserve | quote_exact_in(3) output |
get_limits |
|---|---|---|---|---|
| X → Y | 3 * Q96 / 4 |
0 | 1 | (0, 0) |
| X → Y | 3 * Q96 / 4 |
1 | 1 | (0, 0) |
| Y → X | floor(4 * Q96 / 3) |
0 | 1 | (0, 0) |
| Y → X | floor(4 * Q96 / 3) |
1 | 1 | (0, 0) |
With input reserve 1, the soft_limit branch starts at 2, which is still too small to produce output. Halving after rejection then incorrectly concludes that the direction has no capacity. Consumers using these limits will skip a tradable direction.
Please make the probe/search account for the minimum input needed to produce positive output, distinguishing undersized quotes from quotes exceeding available capacity. Regression coverage should include both directions and both zero and small nonzero input reserves. These are synthetic rounding-boundary cases, not observed mainnet failures; the existing 36 LunarBase tests pass but do not catch them.
…ltiplier - Removed `quote_caller` from bootstrap states and protocol components. - Eliminated `blacklist_fee_multiplier` and related events from the ABI and state management. - Updated JSON bootstrap files to reflect changes in attributes. - Adjusted integration tests to account for the removal of quote_caller. - Cleaned up event handling logic to ignore deprecated events. - Simplified configuration parsing by removing quote_caller requirement.
…nimum trade limits
| # This historical range predates router whitelisting. Execution comparison | ||
| # requires a whitelisted router; recapture a later range for on-chain parity. |
There was a problem hiding this comment.
[P2] Update the Base execution fixture to satisfy the whitelist assumption
The simulator now always uses fee multiplier 1, but this range still ends at block 51297765, where the configured Base router (0xAbA5B53b03eAfaD1C5fc8BD5Fc765fC85Bb3de67) is not whitelisted and pays multiplier 100. Execution comparison remains enabled, and the harness does not override LunarBase's whitelist. Adding this comment does not make the configured test environment satisfy the new assumption.
I read the pool state and quotes at block 51297765, using that router as from, and passed the same state into the current simulator:
| Direction / input | On-chain quote | Current simulator |
|---|---|---|
| X → Y / 0.001 ETH | 2,390,779 | 2,511,757 |
| Y → X / 1 USDC | 393,595,800,163,007 | 397,890,571,043,066 |
Both differences exceed the harness's 0.5% execution tolerance. Passing multiplier 100 into the math library reproduces the on-chain outputs exactly, isolating the caller-policy mismatch. These are block-pinned quote comparisons; I did not run the full range/fork execution test.
Please recapture the parent snapshot and range for an execution router verified to have multiplier-one policy, or explicitly configure and validate a whitelisted fork environment and document that state override. Keep the two-direction execution comparison enabled so this test validates the model it now assumes.
Pool v0.4 applies punishment to the current swap and changes the directional fees used by later quotes. The previous LunarBase integration used the older math and state schema, so updating the ABI alone could leave simulated quotes inconsistent with the pool.
This change updates LunarBase to Pool v0.4.1 and adds BSC indexing:
lunarbase-pmm-math0.4.1, the full uint160 anchor, maximum punishment, and indexed caller fee policy.Substreams package 0.2.0 changes the state schema. It requires the matching simulator and a fresh replay for the configured quote caller.
Validation at
4e1b7a0bf4e0e18423bb32d999f1937f7a79da8bin the fork:d58c29d2ab71fb3821f4ce4eff22d3edf0803583has no conflicts and retains only the 30 changed files.Draft validation limits:
RUSTSEC-2026-0285forrustls0.23.31, inherited unchanged from the branch base. This commit changes onlylunarbase-pmm-mathin the root lockfile. Current upstream already usesrustls0.23.45.PROTOCOL, while Docker Compose readsPROTOCOLS; this also needs to be reconciled for a complete range run. No general workflow changes are included here.