Skip to content

Commit d9c2a27

Browse files
feat(orc-458): add twg set-limits command
1 parent a52356e commit d9c2a27

File tree

4 files changed

+96
-18
lines changed

4 files changed

+96
-18
lines changed

contracts/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export * from './split-main';
2424
export * from './staking-module';
2525
export * from './staking-router';
2626
export * from './token-manager';
27+
export * from './twg';
2728
export * from './unlimited-stake';
2829
export * from './voting';
2930
export * from './withdrawal-request';

programs/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export * from './sanity-checker';
2828
export * from './scripts';
2929
export * from './simple-dvt';
3030
export * from './staking-router';
31+
export * from './twg';
3132
export * from './tx';
3233
export * from './unlimited-stake';
3334
export * from './validators';

programs/twg.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { program } from '@command';
2+
import { twgContract } from '@contracts';
3+
import { logger } from '@utils';
4+
5+
const twg = program.command('twg').description('interact with Triggerable Withdrawals Gateway contract');
6+
7+
// Set limits command
8+
twg
9+
.command('set-limits')
10+
.description('Change exit limits on TWG contract')
11+
.option('--max-exit-requests-limit <limit>', 'Maximum exit requests limit')
12+
.option('--exits-per-frame <exits>', 'Number of exits per frame')
13+
.option('--frame-duration <duration>', 'Frame duration in seconds')
14+
.action(async (options) => {
15+
const { maxExitRequestsLimit, exitsPerFrame, frameDuration } = options;
16+
17+
// Validate required parameters
18+
if (!maxExitRequestsLimit || !exitsPerFrame || !frameDuration) {
19+
logger.error('All parameters are required:');
20+
logger.log(' --max-exit-requests-limit <limit>');
21+
logger.log(' --exits-per-frame <exits>');
22+
logger.log(' --frame-duration <duration>');
23+
logger.log('');
24+
logger.log('Example usage:');
25+
logger.log(' lido-cli twg set-limits --max-exit-requests-limit 11200 --exits-per-frame 1 --frame-duration 48');
26+
return;
27+
}
28+
29+
// Parse and validate parameters
30+
const maxLimit = parseInt(maxExitRequestsLimit, 10);
31+
const exitsPerFrameNum = parseInt(exitsPerFrame, 10);
32+
const frameDurationNum = parseInt(frameDuration, 10);
33+
34+
if (isNaN(maxLimit) || isNaN(exitsPerFrameNum) || isNaN(frameDurationNum)) {
35+
logger.error('All parameters must be valid numbers');
36+
return;
37+
}
38+
39+
if (maxLimit <= 0 || exitsPerFrameNum <= 0 || frameDurationNum <= 0) {
40+
logger.error('All parameters must be positive numbers');
41+
return;
42+
}
43+
44+
try {
45+
logger.log('Setting exit limits on TWG contract...');
46+
logger.log('Contract address:', twgContract.target);
47+
logger.log('Parameters:');
48+
logger.log(' Max exit requests limit:', maxLimit);
49+
logger.log(' Exits per frame:', exitsPerFrameNum);
50+
logger.log(' Frame duration (seconds):', frameDurationNum);
51+
52+
const txResult = await twgContract.setExitRequestLimit(maxLimit, exitsPerFrameNum, frameDurationNum);
53+
54+
logger.log('Transaction hash:', txResult.hash);
55+
logger.log('Waiting for transaction confirmation...');
56+
57+
const receipt = await txResult.wait();
58+
59+
if (receipt.status === 1) {
60+
logger.log('Exit limits updated successfully!');
61+
logger.log('Transaction confirmed in block:', receipt.blockNumber);
62+
} else {
63+
logger.error('Transaction failed');
64+
}
65+
} catch (error) {
66+
logger.error('Failed to set exit limits:', error);
67+
}
68+
});

tests/test-tw-commands.sh

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,11 @@ start_anvil() {
115115
--port $ANVIL_PORT \
116116
--host 0.0.0.0 \
117117
--accounts 10 \
118-
--balance 100 \
119-
--chain-id 560048 &
118+
--balance 100000 \
119+
--chain-id 560048 \
120+
--base-fee 0 \
121+
--gas-price 1 \
122+
--gas-limit 30000000 &
120123

121124
ANVIL_PID=$!
122125

@@ -140,6 +143,8 @@ setup_test_permissions() {
140143
local ADMIN_ACCOUNT="0x0534aA41907c9631fae990960bCC72d75fA7cfeD"
141144
local SUBMITTER_ROLE="0x22ebb4dbafb72948800c1e1afa1688772a1a4cfc54d5ebfcec8163b1139c082e"
142145
local EXIT_REQUEST_LIMIT_MANAGER_ROLE="0x9c616dd118785b2e2fccf45a4ff151a335ff7b6a84cd1c4d7fd9f97f39ea9342"
146+
local TWG_CONTRACT="0x6679090D92b08a2a686eF8614feECD8cDFE209db"
147+
local TW_EXIT_LIMIT_MANAGER_ROLE="0x03c30da9b9e4d4789ac88a294d39a63058ca4a498804c2aa823e381df59d0cf4"
143148

144149
print_status "Impersonating Aragon Agent and granting role..."
145150

@@ -153,9 +158,9 @@ setup_test_permissions() {
153158
-d "{\"jsonrpc\":\"2.0\",\"method\":\"anvil_setBalance\",\"params\":[\"$ADMIN_ACCOUNT\",\"0x56BC75E2D630E0000\"],\"id\":1}" \
154159
http://localhost:$ANVIL_PORT >/dev/null
155160

156-
# Give ETH to test account (1000 ETH to ensure enough for all tests)
161+
# Give ETH to test account (1000000 ETH to ensure enough for all tests even with high gas)
157162
curl -s -X POST -H "Content-Type: application/json" \
158-
-d "{\"jsonrpc\":\"2.0\",\"method\":\"anvil_setBalance\",\"params\":[\"$TEST_ACCOUNT\",\"0x3635C9ADC5DEA00000\"],\"id\":1}" \
163+
-d "{\"jsonrpc\":\"2.0\",\"method\":\"anvil_setBalance\",\"params\":[\"$TEST_ACCOUNT\",\"0xD3C21BCECCEDA1000000\"],\"id\":1}" \
159164
http://localhost:$ANVIL_PORT >/dev/null
160165

161166
# Grant submitter role using cast
@@ -174,6 +179,14 @@ setup_test_permissions() {
174179
--unlocked \
175180
--gas-limit 200000 >/dev/null 2>&1
176181

182+
# Grant TWG limit manager role using cast
183+
print_status "Granting TWG exit request limit manager role to test account..."
184+
ETH_FROM=$ADMIN_ACCOUNT cast send $TWG_CONTRACT "grantRole(bytes32,address)" \
185+
$TW_EXIT_LIMIT_MANAGER_ROLE $TEST_ACCOUNT \
186+
--rpc-url http://localhost:$ANVIL_PORT \
187+
--unlocked \
188+
--gas-limit 200000 >/dev/null 2>&1
189+
177190
print_success "Test permissions setup completed"
178191
sleep 1
179192
}
@@ -195,6 +208,11 @@ run_test_command() {
195208
export EL_NETWORK_NAME="hoodi"
196209
export EL_API_PROVIDER="http://localhost:$ANVIL_PORT"
197210

211+
# Refill balance before each test to avoid gas issues
212+
curl -s -X POST -H "Content-Type: application/json" \
213+
-d "{\"jsonrpc\":\"2.0\",\"method\":\"anvil_setBalance\",\"params\":[\"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266\",\"0x152D02C7E14AF6800000\"],\"id\":1}" \
214+
http://localhost:$ANVIL_PORT >/dev/null
215+
198216
# Run command with output to both console and file
199217
echo "--- Command output ---"
200218

@@ -236,35 +254,25 @@ run_tests() {
236254
local test_data='1,15,12345,0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
237255

238256
# Test 1: Test submit-hash command with calculated hash from test data
239-
print_status "Testing submit-hash with hash calculated from test data..."
240257
run_test_command "Submit hash calculated from data" \
241258
"../run.sh vebo submit-hash --calldata 0x000001000000000f00000000000030391234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef --format 1"
242259

243260
# Test 2: Test submit-data command with the same data used for hash calculation
244-
print_status "Testing submit-data with matching data..."
245-
print_status "Note: This test uses the same data that was used to calculate the hash"
246261
run_test_command "Submit data with matching hash" \
247262
"../run.sh vebo submit-data --data '$test_data'"
248263

249264
# Test 3: Test trigger-exit command with the submitted data
250-
print_status "Testing trigger-exit with the submitted data..."
251-
print_status "Note: This test uses the same calldata that was submitted in previous tests"
252265
run_test_command "Trigger exit with submitted data" \
253266
"../run.sh vebo trigger-exit --calldata 0x000001000000000f00000000000030391234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef --format 1 --value 0.001"
254267

255268
# Test 4: Test set-limits command with valid parameters
256-
print_status "Testing set-limits with valid parameters..."
257-
print_status "Note: This test sets new exit request limits on the VEB contract"
258-
259-
# Ensure test account has enough ETH for this expensive transaction
260-
print_status "Ensuring sufficient ETH balance for set-limits test..."
261-
curl -s -X POST -H "Content-Type: application/json" \
262-
-d "{\"jsonrpc\":\"2.0\",\"method\":\"anvil_setBalance\",\"params\":[\"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266\",\"0x3635C9ADC5DEA00000\"],\"id\":1}" \
263-
http://localhost:$ANVIL_PORT >/dev/null
264-
265269
run_test_command "Set exit request limits" \
266270
"../run.sh vebo set-limits --max-exit-requests-limit 11200 --exits-per-frame 1 --frame-duration 48"
267271

272+
# Test 5: Test TWG set-limits command with valid parameters
273+
run_test_command "Set TWG exit request limits" \
274+
"../run.sh twg set-limits --max-exit-requests-limit 11200 --exits-per-frame 1 --frame-duration 48"
275+
268276
print_status "Test suite completed"
269277
}
270278

0 commit comments

Comments
 (0)