fix: update e2e tests for public recenter() — remove recenterAccess references

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 <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-14 01:44:15 +00:00
parent 02b055ceb9
commit 9b53f409b7

View file

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