Skip to content

Commit 7e23f5e

Browse files
vm/eip6110: log layout check
1 parent 4c50c51 commit 7e23f5e

File tree

1 file changed

+48
-5
lines changed

1 file changed

+48
-5
lines changed

packages/vm/src/requests.ts

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
EthereumJSErrorWithoutCode,
66
bigIntToAddressBytes,
77
bigIntToBytes,
8+
bytesToBigInt,
89
bytesToHex,
910
bytesToInt,
1011
concatBytes,
@@ -16,6 +17,18 @@ import type { RunTxResult } from './types.ts'
1617
import type { VM } from './vm.ts'
1718

1819
const DEPOSIT_TOPIC = '0x649bbc62d0e31342afea4e5cd82d4049e7e1ee912fc0889aa790803be39038c5'
20+
const PUBKEY_OFFSET = BigInt(160)
21+
const WITHDRAWAL_CREDENTIALS_OFFSET = BigInt(256)
22+
const AMOUNT_OFFSET = BigInt(320)
23+
const SIGNATURE_OFFSET = BigInt(384)
24+
const INDEX_OFFSET = BigInt(512)
25+
const PUBKEY_SIZE = 48
26+
const WITHDRAWAL_CREDENTIALS_SIZE = 32
27+
const AMOUNT_SIZE = 8
28+
const SIGNATURE_SIZE = 96
29+
const INDEX_SIZE = 8
30+
const LOG_SIZE = 576
31+
const LOG_LAYOUT_MISMATCH = 'invalid deposit log: unsupported data layout'
1932

2033
/**
2134
* This helper method generates a list of all CL requests that can be included in a pending block
@@ -158,6 +171,9 @@ const accumulateDepositsRequest = (
158171
}
159172

160173
function parseDepositLog(requestData: Uint8Array) {
174+
if (requestData.length !== LOG_SIZE) {
175+
throw EthereumJSErrorWithoutCode(LOG_LAYOUT_MISMATCH)
176+
}
161177
// Extracts validator pubkey, withdrawal credential, deposit amount, signature,
162178
// and validator index from Deposit Event log.
163179
// The event fields are non-indexed so contained in one byte array (log[2]) so parsing is as follows:
@@ -166,19 +182,46 @@ function parseDepositLog(requestData: Uint8Array) {
166182
// 3. Read 32 bytes starting with the first field position to get the size of the first field
167183
// 4. Read the bytes from first field position + 32 + the size of the first field to get the first field value
168184
// 5. Repeat steps 3-4 for each field
169-
const pubKeyIdx = bytesToInt(requestData.slice(0, 32))
185+
const pubKeyIdxBigInt = bytesToBigInt(requestData.slice(0, 32))
186+
const withdrawalCreditsIdxBigInt = bytesToBigInt(requestData.slice(32, 64))
187+
const amountIdxBigInt = bytesToBigInt(requestData.slice(64, 96))
188+
const sigIdxBigInt = bytesToBigInt(requestData.slice(96, 128))
189+
const indexIdxBigInt = bytesToBigInt(requestData.slice(128, 160))
190+
191+
if (
192+
pubKeyIdxBigInt !== PUBKEY_OFFSET ||
193+
withdrawalCreditsIdxBigInt !== WITHDRAWAL_CREDENTIALS_OFFSET ||
194+
amountIdxBigInt !== AMOUNT_OFFSET ||
195+
sigIdxBigInt !== SIGNATURE_OFFSET ||
196+
indexIdxBigInt !== INDEX_OFFSET
197+
) {
198+
throw EthereumJSErrorWithoutCode(LOG_LAYOUT_MISMATCH)
199+
}
200+
201+
const pubKeyIdx = Number(pubKeyIdxBigInt)
202+
const withdrawalCreditsIdx = Number(withdrawalCreditsIdxBigInt)
203+
const amountIdx = Number(amountIdxBigInt)
204+
const sigIdx = Number(sigIdxBigInt)
205+
const indexIdx = Number(indexIdxBigInt)
206+
170207
const pubKeySize = bytesToInt(requestData.slice(pubKeyIdx, pubKeyIdx + 32))
171-
const withdrawalCreditsIdx = bytesToInt(requestData.slice(32, 64))
172208
const withdrawalCreditsSize = bytesToInt(
173209
requestData.slice(withdrawalCreditsIdx, withdrawalCreditsIdx + 32),
174210
)
175-
const amountIdx = bytesToInt(requestData.slice(64, 96))
176211
const amountSize = bytesToInt(requestData.slice(amountIdx, amountIdx + 32))
177-
const sigIdx = bytesToInt(requestData.slice(96, 128))
178212
const sigSize = bytesToInt(requestData.slice(sigIdx, sigIdx + 32))
179-
const indexIdx = bytesToInt(requestData.slice(128, 160))
180213
const indexSize = bytesToInt(requestData.slice(indexIdx, indexIdx + 32))
181214

215+
if (
216+
pubKeySize !== PUBKEY_SIZE ||
217+
withdrawalCreditsSize !== WITHDRAWAL_CREDENTIALS_SIZE ||
218+
amountSize !== AMOUNT_SIZE ||
219+
sigSize !== SIGNATURE_SIZE ||
220+
indexSize !== INDEX_SIZE
221+
) {
222+
throw EthereumJSErrorWithoutCode(LOG_LAYOUT_MISMATCH)
223+
}
224+
182225
const pubkey = requestData.slice(pubKeyIdx + 32, pubKeyIdx + 32 + pubKeySize)
183226
const withdrawalCredentials = requestData.slice(
184227
withdrawalCreditsIdx + 32,

0 commit comments

Comments
 (0)