From 9b53f409b770510bf55e616b6c9c0ab2ec3e2b73 Mon Sep 17 00:00:00 2001 From: openhands Date: Sat, 14 Mar 2026 01:44:15 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20update=20e2e=20tests=20for=20public=20re?= =?UTF-8?q?center()=20=E2=80=94=20remove=20recenterAccess=20references?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit recenterAccess() was removed from LiquidityManager in this PR. The old tests called recenterAccess() (selector 0xdef51130) which now reverts, causing both recenter tests to fail. Update tests to match the new public recenter() behavior: - Test 1: verify any address may call recenter() without "access denied" - Test 2: same caller pattern, guard errors are still acceptable Co-Authored-By: Claude Sonnet 4.6 --- tests/e2e/04-recenter-positions.spec.ts | 49 ++++++++++--------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/tests/e2e/04-recenter-positions.spec.ts b/tests/e2e/04-recenter-positions.spec.ts index 9b504d6..aa82106 100644 --- a/tests/e2e/04-recenter-positions.spec.ts +++ b/tests/e2e/04-recenter-positions.spec.ts @@ -7,7 +7,6 @@ const STACK_RPC_URL = STACK_CONFIG.rpcUrl; // Solidity function selectors const POSITIONS_SELECTOR = '0xf86aafc0'; // positions(uint8) const RECENTER_SELECTOR = '0xf46e1346'; // recenter() -const RECENTER_ACCESS_SELECTOR = '0xdef51130'; // recenterAccess() // Position stages (matches ThreePositionStrategy.Stage enum) const STAGE_FLOOR = 0; @@ -102,50 +101,42 @@ test.describe('Recenter Positions', () => { console.log('[TEST] All three positions have non-zero liquidity'); }); - test('recenter() enforces access control', async () => { + test('recenter() is public — any address may attempt it', async () => { const lmAddress = STACK_CONFIG.contracts.LiquidityManager; - // Read the recenterAccess address - const recenterAccessResult = (await rpcCall('eth_call', [ - { to: lmAddress, data: RECENTER_ACCESS_SELECTOR }, - 'latest', - ])) as string; - const recenterAddr = '0x' + recenterAccessResult.slice(26); - console.log(`[TEST] recenterAccess: ${recenterAddr}`); - expect(recenterAddr).not.toBe('0x' + '0'.repeat(40)); - console.log('[TEST] recenterAccess is set (not zero address)'); - - // Try calling recenter from an unauthorized address — should revert with "access denied" - const unauthorizedAddr = '0x1111111111111111111111111111111111111111'; + // recenter() is now public: anyone can call it (recenterAccess was removed). + // After bootstrap the cooldown and amplitude guards will typically fire, + // but the revert reason must NOT be "access denied". + const callerAddr = '0x1111111111111111111111111111111111111111'; const callResult = await rpcCallRaw('eth_call', [ - { from: unauthorizedAddr, to: lmAddress, data: RECENTER_SELECTOR }, + { from: callerAddr, to: lmAddress, data: RECENTER_SELECTOR }, 'latest', ]); - expect(callResult.error).toBeDefined(); - expect(callResult.error!.message).toContain('access denied'); - console.log('[TEST] Unauthorized recenter correctly rejected with "access denied"'); + if (callResult.error) { + // Acceptable guard errors: cooldown, amplitude, TWAP — NOT access control + const msg = callResult.error.message ?? ''; + expect(msg).not.toContain('access denied'); + console.log(`[TEST] Recenter guard active (expected): ${msg}`); + console.log('[TEST] No "access denied" — access control correctly removed'); + } else { + console.log('[TEST] Recenter succeeded from arbitrary address — access control is gone'); + } }); test('recenter() enforces amplitude check', async () => { const lmAddress = STACK_CONFIG.contracts.LiquidityManager; - // Read the recenterAccess address - const recenterAccessResult = (await rpcCall('eth_call', [ - { to: lmAddress, data: RECENTER_ACCESS_SELECTOR }, - 'latest', - ])) as string; - const recenterAddr = '0x' + recenterAccessResult.slice(26); - - // Call recenter from the authorized address without moving the price - // Should revert with "amplitude not reached" since price hasn't moved enough + // Call recenter from any address without moving the price. + // Should revert with a guard error (cooldown, amplitude, or TWAP), not crash. + const callerAddr = '0x1111111111111111111111111111111111111111'; const callResult = await rpcCallRaw('eth_call', [ - { from: recenterAddr, to: lmAddress, data: RECENTER_SELECTOR }, + { from: callerAddr, to: lmAddress, data: RECENTER_SELECTOR }, 'latest', ]); // After bootstrap's initial swap + recenter, calling recenter again may either: - // - Fail with "amplitude not reached" if price hasn't moved enough + // - Fail with "amplitude not reached" / "recenter cooldown" / "price deviated from oracle" // - Succeed if contract's amplitude threshold allows it (e.g., after swap moved price) // Both outcomes are valid — the key invariant is that recenter doesn't crash unexpectedly if (callResult.error) {