|
3 | 3 | bigIntToAddressBytes, |
4 | 4 | bigIntToBytes, |
5 | 5 | bytesToHex, |
| 6 | + bytesToInt, |
6 | 7 | createAddressFromString, |
7 | 8 | setLengthLeft, |
8 | 9 | } from '@ethereumjs/util' |
@@ -127,11 +128,59 @@ const accumulateDepositsRequest = ( |
127 | 128 | txResults: RunTxResult[], |
128 | 129 | ): CLRequest<CLRequestType.Deposit> => { |
129 | 130 | let resultsBytes = new Uint8Array(0) |
| 131 | + const depositContractAddressLowerCase = depositContractAddress.toLowerCase() |
130 | 132 | for (const [_, tx] of txResults.entries()) { |
131 | 133 | for (let i = 0; i < tx.receipt.logs.length; i++) { |
132 | 134 | const log = tx.receipt.logs[i] |
133 | | - if (bytesToHex(log[0]).toLowerCase() === depositContractAddress.toLowerCase()) { |
134 | | - resultsBytes = concatBytes(resultsBytes, log[2]) |
| 135 | + if (bytesToHex(log[0]).toLowerCase() === depositContractAddressLowerCase) { |
| 136 | + // Extracts validator pubkey, withdrawal credential, deposit amount, signature, |
| 137 | + // and validator index from Deposit Event log. |
| 138 | + // The event fields are non-indexed so contained in one byte array (log[2]) so parsing is as follows: |
| 139 | + // 1. Read the first 32 bytes to get the starting position of the first field. |
| 140 | + // 2. Continue reading the byte array in 32 byte increments to get all the field starting positions |
| 141 | + // 3. Read 32 bytes starting with the first field position to get the size of the first field |
| 142 | + // 4. Read the bytes from first field position + 32 + the size of the first field to get the first field value |
| 143 | + // 5. Repeat steps 3-4 for each field |
| 144 | + // This is equivalent to ABI-decoding the event: |
| 145 | + // event DepositEvent( |
| 146 | + // bytes pubkey, |
| 147 | + // bytes withdrawal_credentials, |
| 148 | + // bytes amount, |
| 149 | + // bytes signature, |
| 150 | + // bytes index |
| 151 | + //); |
| 152 | + |
| 153 | + const pubKeyIdx = bytesToInt(log[2].slice(0, 32)) |
| 154 | + const pubKeySize = bytesToInt(log[2].slice(pubKeyIdx, pubKeyIdx + 32)) |
| 155 | + const withdrawalCreditsIdx = bytesToInt(log[2].slice(32, 64)) |
| 156 | + const withdrawalCreditsSize = bytesToInt( |
| 157 | + log[2].slice(withdrawalCreditsIdx, withdrawalCreditsIdx + 32), |
| 158 | + ) |
| 159 | + const amountIdx = bytesToInt(log[2].slice(64, 96)) |
| 160 | + const amountSize = bytesToInt(log[2].slice(amountIdx, amountIdx + 32)) |
| 161 | + const sigIdx = bytesToInt(log[2].slice(96, 128)) |
| 162 | + const sigSize = bytesToInt(log[2].slice(sigIdx, sigIdx + 32)) |
| 163 | + const indexIdx = bytesToInt(log[2].slice(128, 160)) |
| 164 | + const indexSize = bytesToInt(log[2].slice(indexIdx, indexIdx + 32)) |
| 165 | + |
| 166 | + const pubkey = log[2].slice(pubKeyIdx + 32, pubKeyIdx + 32 + pubKeySize) |
| 167 | + const withdrawalCredentials = log[2].slice( |
| 168 | + withdrawalCreditsIdx + 32, |
| 169 | + withdrawalCreditsIdx + 32 + withdrawalCreditsSize, |
| 170 | + ) |
| 171 | + const amount = log[2].slice(amountIdx + 32, amountIdx + 32 + amountSize) |
| 172 | + const signature = log[2].slice(sigIdx + 32, sigIdx + 32 + sigSize) |
| 173 | + const index = log[2].slice(indexIdx + 32, indexIdx + 32 + indexSize) |
| 174 | + |
| 175 | + const depositRequestBytes = concatBytes( |
| 176 | + pubkey, |
| 177 | + withdrawalCredentials, |
| 178 | + amount, |
| 179 | + signature, |
| 180 | + index, |
| 181 | + ) |
| 182 | + |
| 183 | + resultsBytes = concatBytes(resultsBytes, depositRequestBytes) |
135 | 184 | } |
136 | 185 | } |
137 | 186 | } |
|
0 commit comments