Deploy scripts (DeployLocal.sol and DeployBase.sol) now execute a seed buy + double-recenter sequence before handing control to users: 1. Temporarily grant deployer recenterAccess (via self as feeDestination) 2. Fund LM with a small amount and call recenter() -> places thin positions 3. SeedSwapper executes a small buy, generating a non-zero WETH fee 4. Second recenter() hits the cumulativeVolume==0 bootstrap path with ethFee>0 -> _recordVolumeAndPrice fires -> cumulativeVolume>0 5. Revoke recenterAccess and restore the real feeDestination After deployment, cumulativeVolume>0, so the bootstrap path is unreachable by external users and cannot be front-run by an attacker inflating the initial VWAP anchor with a whale buy. Also adds: - tools/deploy-optimizer.sh: verification step checks cumulativeVolume>0 after a fresh local deployment - test_vwapBootstrappedBySeedTrade() in VWAPFloorProtection.t.sol: confirms the deploy sequence (recenter + buy + recenter) leaves cumulativeVolume>0 and getVWAP()>0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b456bc75fd
commit
c05b20d640
4 changed files with 278 additions and 20 deletions
|
|
@ -212,6 +212,42 @@ contract VWAPFloorProtectionTest is UniSwapHelper {
|
|||
}
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Deployment bootstrap: seed trade seeds VWAP before protocol goes live
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* @notice Verifies the deployment bootstrap sequence from DeployLocal.sol / DeployBase.sol.
|
||||
*
|
||||
* The deploy scripts execute:
|
||||
* 1. First recenter — places bootstrap positions; no fees, cumulativeVolume stays 0.
|
||||
* 2. Seed buy — small swap generates a non-zero WETH fee in the anchor position
|
||||
* and moves the tick >400 (amplitude gate for the second recenter).
|
||||
* 3. Second recenter — cumulativeVolume==0 path fires (shouldRecordVWAP=true) and
|
||||
* ethFee>0, so _recordVolumeAndPrice is called.
|
||||
*
|
||||
* After step 3, cumulativeVolume>0 and the bootstrap path is permanently closed to
|
||||
* external users. This test mirrors that sequence and asserts the invariant holds.
|
||||
*/
|
||||
function test_vwapBootstrappedBySeedTrade() public {
|
||||
// Step 1: Initial recenter — places positions, no fees yet.
|
||||
vm.prank(RECENTER_CALLER);
|
||||
lm.recenter();
|
||||
assertEq(lm.cumulativeVolume(), 0, "no fees before seed trade: cumulativeVolume must be 0");
|
||||
|
||||
// Step 2: Seed buy — enough to move the tick >400 (amplitude gate) and generate fee.
|
||||
// 25 ether against a 100 ETH LM pool reliably satisfies the amplitude check
|
||||
// (same amount used across other bootstrap tests in this file).
|
||||
buyRaw(25 ether);
|
||||
|
||||
// Step 3: Second recenter — bootstrap path records VWAP.
|
||||
vm.prank(RECENTER_CALLER);
|
||||
lm.recenter();
|
||||
|
||||
assertGt(lm.cumulativeVolume(), 0, "seed trade must bootstrap cumulativeVolume to non-zero");
|
||||
assertGt(lm.getVWAP(), 0, "seed trade must anchor VWAP to the real launch price");
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// getLiquidityManager override for UniSwapHelper boundary helpers
|
||||
// =========================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue