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) {