arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/eth/wdelayer.go
eth/wdelayer.goRaw
  1package eth
  2
  3import (
  4	"context"
  5	"fmt"
  6	"math/big"
  7	"strings"
  8
  9	"github.com/ethereum/go-ethereum"
 10	"github.com/ethereum/go-ethereum/accounts/abi"
 11	"github.com/ethereum/go-ethereum/accounts/abi/bind"
 12	ethCommon "github.com/ethereum/go-ethereum/common"
 13	"github.com/ethereum/go-ethereum/core/types"
 14	"github.com/ethereum/go-ethereum/crypto"
 15	"github.com/ethereum/go-ethereum/ethclient"
 16	"github.com/hermeznetwork/hermez-node/common"
 17	WithdrawalDelayer "github.com/hermeznetwork/hermez-node/eth/contracts/withdrawdelayer"
 18	"github.com/hermeznetwork/hermez-node/log"
 19	"github.com/hermeznetwork/tracerr"
 20)
 21
 22// DepositState is the state of Deposit
 23type DepositState struct {
 24	Amount           *big.Int
 25	DepositTimestamp uint64
 26}
 27
 28// WDelayerEventInitialize is the InitializeWithdrawalDelayerEvent event of the
 29// Smart Contract
 30type WDelayerEventInitialize struct {
 31	InitialWithdrawalDelay         uint64
 32	InitialHermezGovernanceAddress ethCommon.Address
 33	InitialEmergencyCouncil        ethCommon.Address
 34}
 35
 36// WDelayerVariables returns the WDelayerVariables from the initialize event
 37func (ei *WDelayerEventInitialize) WDelayerVariables() *common.WDelayerVariables {
 38	return &common.WDelayerVariables{
 39		EthBlockNum:                0,
 40		HermezGovernanceAddress:    ei.InitialHermezGovernanceAddress,
 41		EmergencyCouncilAddress:    ei.InitialEmergencyCouncil,
 42		WithdrawalDelay:            ei.InitialWithdrawalDelay,
 43		EmergencyModeStartingBlock: 0,
 44		EmergencyMode:              false,
 45	}
 46}
 47
 48// WDelayerEventDeposit is an event of the WithdrawalDelayer Smart Contract
 49type WDelayerEventDeposit struct {
 50	Owner            ethCommon.Address
 51	Token            ethCommon.Address
 52	Amount           *big.Int
 53	DepositTimestamp uint64
 54	TxHash           ethCommon.Hash // Hash of the transaction that generated this event
 55}
 56
 57// WDelayerEventWithdraw is an event of the WithdrawalDelayer Smart Contract
 58type WDelayerEventWithdraw struct {
 59	Owner  ethCommon.Address
 60	Token  ethCommon.Address
 61	Amount *big.Int
 62}
 63
 64// WDelayerEventEmergencyModeEnabled an event of the WithdrawalDelayer Smart Contract
 65type WDelayerEventEmergencyModeEnabled struct {
 66}
 67
 68// WDelayerEventNewWithdrawalDelay an event of the WithdrawalDelayer Smart Contract
 69type WDelayerEventNewWithdrawalDelay struct {
 70	WithdrawalDelay uint64
 71}
 72
 73// WDelayerEventEscapeHatchWithdrawal an event of the WithdrawalDelayer Smart Contract
 74type WDelayerEventEscapeHatchWithdrawal struct {
 75	Who    ethCommon.Address
 76	To     ethCommon.Address
 77	Token  ethCommon.Address
 78	Amount *big.Int
 79}
 80
 81// WDelayerEventNewEmergencyCouncil an event of the WithdrawalDelayer Smart Contract
 82type WDelayerEventNewEmergencyCouncil struct {
 83	NewEmergencyCouncil ethCommon.Address
 84}
 85
 86// WDelayerEventNewHermezGovernanceAddress an event of the WithdrawalDelayer Smart Contract
 87type WDelayerEventNewHermezGovernanceAddress struct {
 88	NewHermezGovernanceAddress ethCommon.Address
 89}
 90
 91// WDelayerEvents is the lis of events in a block of the WithdrawalDelayer Smart Contract
 92type WDelayerEvents struct {
 93	Deposit                    []WDelayerEventDeposit
 94	Withdraw                   []WDelayerEventWithdraw
 95	EmergencyModeEnabled       []WDelayerEventEmergencyModeEnabled
 96	NewWithdrawalDelay         []WDelayerEventNewWithdrawalDelay
 97	EscapeHatchWithdrawal      []WDelayerEventEscapeHatchWithdrawal
 98	NewEmergencyCouncil        []WDelayerEventNewEmergencyCouncil
 99	NewHermezGovernanceAddress []WDelayerEventNewHermezGovernanceAddress
100}
101
102// NewWDelayerEvents creates an empty WDelayerEvents with the slices initialized.
103func NewWDelayerEvents() WDelayerEvents {
104	return WDelayerEvents{
105		Deposit:                    make([]WDelayerEventDeposit, 0),
106		Withdraw:                   make([]WDelayerEventWithdraw, 0),
107		EmergencyModeEnabled:       make([]WDelayerEventEmergencyModeEnabled, 0),
108		NewWithdrawalDelay:         make([]WDelayerEventNewWithdrawalDelay, 0),
109		EscapeHatchWithdrawal:      make([]WDelayerEventEscapeHatchWithdrawal, 0),
110		NewEmergencyCouncil:        make([]WDelayerEventNewEmergencyCouncil, 0),
111		NewHermezGovernanceAddress: make([]WDelayerEventNewHermezGovernanceAddress, 0),
112	}
113}
114
115// WDelayerInterface is the inteface to WithdrawalDelayer Smart Contract
116type WDelayerInterface interface {
117	//
118	// Smart Contract Methods
119	//
120
121	WDelayerGetHermezGovernanceAddress() (*ethCommon.Address, error)
122	WDelayerTransferGovernance(newAddress ethCommon.Address) (*types.Transaction, error)
123	WDelayerClaimGovernance() (*types.Transaction, error)
124	WDelayerGetEmergencyCouncil() (*ethCommon.Address, error)
125	WDelayerTransferEmergencyCouncil(newAddress ethCommon.Address) (*types.Transaction, error)
126	WDelayerClaimEmergencyCouncil() (*types.Transaction, error)
127	WDelayerIsEmergencyMode() (bool, error)
128	WDelayerGetWithdrawalDelay() (int64, error)
129	WDelayerGetEmergencyModeStartingTime() (int64, error)
130	WDelayerEnableEmergencyMode() (*types.Transaction, error)
131	WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (*types.Transaction, error)
132	WDelayerDepositInfo(owner, token ethCommon.Address) (depositInfo DepositState, err error)
133	WDelayerDeposit(onwer, token ethCommon.Address, amount *big.Int) (*types.Transaction, error)
134	WDelayerWithdrawal(owner, token ethCommon.Address) (*types.Transaction, error)
135	WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address,
136		amount *big.Int) (*types.Transaction, error)
137
138	WDelayerEventsByBlock(blockNum int64, blockHash *ethCommon.Hash) (*WDelayerEvents, error)
139	WDelayerConstants() (*common.WDelayerConstants, error)
140	WDelayerEventInit(genesisBlockNum int64) (*WDelayerEventInitialize, int64, error)
141}
142
143//
144// Implementation
145//
146
147// WDelayerClient is the implementation of the interface to the WithdrawDelayer
148// Smart Contract in ethereum.
149type WDelayerClient struct {
150	client      *EthereumClient
151	address     ethCommon.Address
152	wdelayer    *WithdrawalDelayer.WithdrawalDelayer
153	contractAbi abi.ABI
154	opts        *bind.CallOpts
155}
156
157// NewWDelayerClient creates a new WDelayerClient
158func NewWDelayerClient(client *EthereumClient, address ethCommon.Address) (*WDelayerClient, error) {
159	contractAbi, err := abi.JSON(strings.NewReader(string(WithdrawalDelayer.WithdrawalDelayerABI)))
160	if err != nil {
161		return nil, tracerr.Wrap(err)
162	}
163	wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(address, client.Client())
164	if err != nil {
165		return nil, tracerr.Wrap(err)
166	}
167	return &WDelayerClient{
168		client:      client,
169		address:     address,
170		wdelayer:    wdelayer,
171		contractAbi: contractAbi,
172		opts:        newCallOpts(),
173	}, nil
174}
175
176// WDelayerGetHermezGovernanceAddress is the interface to call the smart contract function
177func (c *WDelayerClient) WDelayerGetHermezGovernanceAddress() (
178	hermezGovernanceAddress *ethCommon.Address, err error) {
179	var _hermezGovernanceAddress ethCommon.Address
180	if err := c.client.Call(func(ec *ethclient.Client) error {
181		_hermezGovernanceAddress, err = c.wdelayer.GetHermezGovernanceAddress(c.opts)
182		return tracerr.Wrap(err)
183	}); err != nil {
184		return nil, tracerr.Wrap(err)
185	}
186	return &_hermezGovernanceAddress, nil
187}
188
189// WDelayerTransferGovernance is the interface to call the smart contract function
190func (c *WDelayerClient) WDelayerTransferGovernance(newAddress ethCommon.Address) (
191	tx *types.Transaction, err error) {
192	if tx, err = c.client.CallAuth(
193		0,
194		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
195			return c.wdelayer.TransferGovernance(auth, newAddress)
196		},
197	); err != nil {
198		return nil, tracerr.Wrap(fmt.Errorf("Failed transfer hermezGovernanceAddress: %w", err))
199	}
200	return tx, nil
201}
202
203// WDelayerClaimGovernance is the interface to call the smart contract function
204func (c *WDelayerClient) WDelayerClaimGovernance() (tx *types.Transaction, err error) {
205	if tx, err = c.client.CallAuth(
206		0,
207		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
208			return c.wdelayer.ClaimGovernance(auth)
209		},
210	); err != nil {
211		return nil, tracerr.Wrap(fmt.Errorf("Failed claim hermezGovernanceAddress: %w", err))
212	}
213	return tx, nil
214}
215
216// WDelayerGetEmergencyCouncil is the interface to call the smart contract function
217func (c *WDelayerClient) WDelayerGetEmergencyCouncil() (emergencyCouncilAddress *ethCommon.Address,
218	err error) {
219	var _emergencyCouncilAddress ethCommon.Address
220	if err := c.client.Call(func(ec *ethclient.Client) error {
221		_emergencyCouncilAddress, err = c.wdelayer.GetEmergencyCouncil(c.opts)
222		return tracerr.Wrap(err)
223	}); err != nil {
224		return nil, tracerr.Wrap(err)
225	}
226	return &_emergencyCouncilAddress, nil
227}
228
229// WDelayerTransferEmergencyCouncil is the interface to call the smart contract function
230func (c *WDelayerClient) WDelayerTransferEmergencyCouncil(newAddress ethCommon.Address) (
231	tx *types.Transaction, err error) {
232	if tx, err = c.client.CallAuth(
233		0,
234		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
235			return c.wdelayer.TransferEmergencyCouncil(auth, newAddress)
236		},
237	); err != nil {
238		return nil, tracerr.Wrap(fmt.Errorf("Failed transfer EmergencyCouncil: %w", err))
239	}
240	return tx, nil
241}
242
243// WDelayerClaimEmergencyCouncil is the interface to call the smart contract function
244func (c *WDelayerClient) WDelayerClaimEmergencyCouncil() (tx *types.Transaction, err error) {
245	if tx, err = c.client.CallAuth(
246		0,
247		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
248			return c.wdelayer.ClaimEmergencyCouncil(auth)
249		},
250	); err != nil {
251		return nil, tracerr.Wrap(fmt.Errorf("Failed claim EmergencyCouncil: %w", err))
252	}
253	return tx, nil
254}
255
256// WDelayerIsEmergencyMode is the interface to call the smart contract function
257func (c *WDelayerClient) WDelayerIsEmergencyMode() (ermergencyMode bool, err error) {
258	if err := c.client.Call(func(ec *ethclient.Client) error {
259		ermergencyMode, err = c.wdelayer.IsEmergencyMode(c.opts)
260		return tracerr.Wrap(err)
261	}); err != nil {
262		return false, tracerr.Wrap(err)
263	}
264	return ermergencyMode, nil
265}
266
267// WDelayerGetWithdrawalDelay is the interface to call the smart contract function
268func (c *WDelayerClient) WDelayerGetWithdrawalDelay() (withdrawalDelay int64, err error) {
269	var _withdrawalDelay uint64
270	if err := c.client.Call(func(ec *ethclient.Client) error {
271		_withdrawalDelay, err = c.wdelayer.GetWithdrawalDelay(c.opts)
272		return tracerr.Wrap(err)
273	}); err != nil {
274		return 0, tracerr.Wrap(err)
275	}
276	return int64(_withdrawalDelay), nil
277}
278
279// WDelayerGetEmergencyModeStartingTime is the interface to call the smart contract function
280func (c *WDelayerClient) WDelayerGetEmergencyModeStartingTime() (emergencyModeStartingTime int64,
281	err error) {
282	var _emergencyModeStartingTime uint64
283	if err := c.client.Call(func(ec *ethclient.Client) error {
284		_emergencyModeStartingTime, err = c.wdelayer.GetEmergencyModeStartingTime(c.opts)
285		return tracerr.Wrap(err)
286	}); err != nil {
287		return 0, tracerr.Wrap(err)
288	}
289	return int64(_emergencyModeStartingTime), nil
290}
291
292// WDelayerEnableEmergencyMode is the interface to call the smart contract function
293func (c *WDelayerClient) WDelayerEnableEmergencyMode() (tx *types.Transaction, err error) {
294	if tx, err = c.client.CallAuth(
295		0,
296		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
297			return c.wdelayer.EnableEmergencyMode(auth)
298		},
299	); err != nil {
300		return nil, tracerr.Wrap(fmt.Errorf("Failed setting enable emergency mode: %w", err))
301	}
302	return tx, nil
303}
304
305// WDelayerChangeWithdrawalDelay is the interface to call the smart contract function
306func (c *WDelayerClient) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (
307	tx *types.Transaction, err error) {
308	if tx, err = c.client.CallAuth(
309		0,
310		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
311			return c.wdelayer.ChangeWithdrawalDelay(auth, newWithdrawalDelay)
312		},
313	); err != nil {
314		return nil, tracerr.Wrap(fmt.Errorf("Failed setting withdrawal delay: %w", err))
315	}
316	return tx, nil
317}
318
319// WDelayerDepositInfo is the interface to call the smart contract function
320func (c *WDelayerClient) WDelayerDepositInfo(owner, token ethCommon.Address) (
321	depositInfo DepositState, err error) {
322	if err := c.client.Call(func(ec *ethclient.Client) error {
323		amount, depositTimestamp, err := c.wdelayer.DepositInfo(c.opts, owner, token)
324		depositInfo.Amount = amount
325		depositInfo.DepositTimestamp = depositTimestamp
326		return tracerr.Wrap(err)
327	}); err != nil {
328		return depositInfo, tracerr.Wrap(err)
329	}
330	return depositInfo, nil
331}
332
333// WDelayerDeposit is the interface to call the smart contract function
334func (c *WDelayerClient) WDelayerDeposit(owner, token ethCommon.Address, amount *big.Int) (
335	tx *types.Transaction, err error) {
336	if tx, err = c.client.CallAuth(
337		0,
338		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
339			return c.wdelayer.Deposit(auth, owner, token, amount)
340		},
341	); err != nil {
342		return nil, tracerr.Wrap(fmt.Errorf("Failed deposit: %w", err))
343	}
344	return tx, nil
345}
346
347// WDelayerWithdrawal is the interface to call the smart contract function
348func (c *WDelayerClient) WDelayerWithdrawal(owner, token ethCommon.Address) (tx *types.Transaction,
349	err error) {
350	if tx, err = c.client.CallAuth(
351		0,
352		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
353			return c.wdelayer.Withdrawal(auth, owner, token)
354		},
355	); err != nil {
356		return nil, tracerr.Wrap(fmt.Errorf("Failed withdrawal: %w", err))
357	}
358	return tx, nil
359}
360
361// WDelayerEscapeHatchWithdrawal is the interface to call the smart contract function
362func (c *WDelayerClient) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address,
363	amount *big.Int) (tx *types.Transaction, err error) {
364	if tx, err = c.client.CallAuth(
365		0,
366		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
367			return c.wdelayer.EscapeHatchWithdrawal(auth, to, token, amount)
368		},
369	); err != nil {
370		return nil, tracerr.Wrap(fmt.Errorf("Failed escapeHatchWithdrawal: %w", err))
371	}
372	return tx, nil
373}
374
375// WDelayerConstants returns the Constants of the WDelayer Smart Contract
376func (c *WDelayerClient) WDelayerConstants() (constants *common.WDelayerConstants, err error) {
377	constants = new(common.WDelayerConstants)
378	if err := c.client.Call(func(ec *ethclient.Client) error {
379		constants.MaxWithdrawalDelay, err = c.wdelayer.MAXWITHDRAWALDELAY(c.opts)
380		if err != nil {
381			return tracerr.Wrap(err)
382		}
383		constants.MaxEmergencyModeTime, err = c.wdelayer.MAXEMERGENCYMODETIME(c.opts)
384		if err != nil {
385			return tracerr.Wrap(err)
386		}
387		constants.HermezRollup, err = c.wdelayer.HermezRollupAddress(c.opts)
388		if err != nil {
389			return tracerr.Wrap(err)
390		}
391		return tracerr.Wrap(err)
392	}); err != nil {
393		return constants, tracerr.Wrap(err)
394	}
395	return constants, nil
396}
397
398var (
399	logWDelayerDeposit = crypto.Keccak256Hash([]byte(
400		"Deposit(address,address,uint192,uint64)"))
401	logWDelayerWithdraw = crypto.Keccak256Hash([]byte(
402		"Withdraw(address,address,uint192)"))
403	logWDelayerEmergencyModeEnabled = crypto.Keccak256Hash([]byte(
404		"EmergencyModeEnabled()"))
405	logWDelayerNewWithdrawalDelay = crypto.Keccak256Hash([]byte(
406		"NewWithdrawalDelay(uint64)"))
407	logWDelayerEscapeHatchWithdrawal = crypto.Keccak256Hash([]byte(
408		"EscapeHatchWithdrawal(address,address,address,uint256)"))
409	logWDelayerNewEmergencyCouncil = crypto.Keccak256Hash([]byte(
410		"NewEmergencyCouncil(address)"))
411	logWDelayerNewHermezGovernanceAddress = crypto.Keccak256Hash([]byte(
412		"NewHermezGovernanceAddress(address)"))
413	logWDelayerInitialize = crypto.Keccak256Hash([]byte(
414		"InitializeWithdrawalDelayerEvent(uint64,address,address)"))
415)
416
417// WDelayerEventInit returns the initialize event with its corresponding block number
418func (c *WDelayerClient) WDelayerEventInit(genesisBlockNum int64) (*WDelayerEventInitialize, int64, error) {
419	query := ethereum.FilterQuery{
420		Addresses: []ethCommon.Address{
421			c.address,
422		},
423		FromBlock: big.NewInt(max(0, genesisBlockNum-blocksPerDay)),
424		ToBlock:   big.NewInt(genesisBlockNum),
425		Topics:    [][]ethCommon.Hash{{logWDelayerInitialize}},
426	}
427	logs, err := c.client.client.FilterLogs(context.Background(), query)
428	if err != nil {
429		return nil, 0, tracerr.Wrap(err)
430	}
431	if len(logs) != 1 {
432		return nil, 0, tracerr.Wrap(fmt.Errorf("no event of type InitializeWithdrawalDelayerEvent found"))
433	}
434	vLog := logs[0]
435	if vLog.Topics[0] != logWDelayerInitialize {
436		return nil, 0, tracerr.Wrap(fmt.Errorf("event is not InitializeWithdrawalDelayerEvent"))
437	}
438
439	var wDelayerInit WDelayerEventInitialize
440	if err := c.contractAbi.UnpackIntoInterface(&wDelayerInit, "InitializeWithdrawalDelayerEvent",
441		vLog.Data); err != nil {
442		return nil, 0, tracerr.Wrap(err)
443	}
444	return &wDelayerInit, int64(vLog.BlockNumber), tracerr.Wrap(err)
445}
446
447// WDelayerEventsByBlock returns the events in a block that happened in the
448// WDelayer Smart Contract.
449// To query by blockNum, set blockNum >= 0 and blockHash == nil.
450// To query by blockHash set blockHash != nil, and blockNum will be ignored.
451// If there are no events in that block the result is nil.
452func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64,
453	blockHash *ethCommon.Hash) (*WDelayerEvents, error) {
454	var wdelayerEvents WDelayerEvents
455
456	var blockNumBigInt *big.Int
457	if blockHash == nil {
458		blockNumBigInt = big.NewInt(blockNum)
459	}
460	query := ethereum.FilterQuery{
461		BlockHash: blockHash,
462		FromBlock: blockNumBigInt,
463		ToBlock:   blockNumBigInt,
464		Addresses: []ethCommon.Address{
465			c.address,
466		},
467		Topics: [][]ethCommon.Hash{},
468	}
469
470	logs, err := c.client.client.FilterLogs(context.Background(), query)
471	if err != nil {
472		return nil, tracerr.Wrap(err)
473	}
474	if len(logs) == 0 {
475		return nil, nil
476	}
477
478	for _, vLog := range logs {
479		if blockHash != nil && vLog.BlockHash != *blockHash {
480			log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String())
481			return nil, tracerr.Wrap(ErrBlockHashMismatchEvent)
482		}
483		switch vLog.Topics[0] {
484		case logWDelayerDeposit:
485			var deposit WDelayerEventDeposit
486			err := c.contractAbi.UnpackIntoInterface(&deposit, "Deposit", vLog.Data)
487			if err != nil {
488				return nil, tracerr.Wrap(err)
489			}
490			deposit.Owner = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
491			deposit.Token = ethCommon.BytesToAddress(vLog.Topics[2].Bytes())
492			deposit.TxHash = vLog.TxHash
493			wdelayerEvents.Deposit = append(wdelayerEvents.Deposit, deposit)
494
495		case logWDelayerWithdraw:
496			var withdraw WDelayerEventWithdraw
497			err := c.contractAbi.UnpackIntoInterface(&withdraw, "Withdraw", vLog.Data)
498			if err != nil {
499				return nil, tracerr.Wrap(err)
500			}
501			withdraw.Token = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
502			withdraw.Owner = ethCommon.BytesToAddress(vLog.Topics[2].Bytes())
503			wdelayerEvents.Withdraw = append(wdelayerEvents.Withdraw, withdraw)
504
505		case logWDelayerEmergencyModeEnabled:
506			var emergencyModeEnabled WDelayerEventEmergencyModeEnabled
507			wdelayerEvents.EmergencyModeEnabled =
508				append(wdelayerEvents.EmergencyModeEnabled, emergencyModeEnabled)
509
510		case logWDelayerNewWithdrawalDelay:
511			var withdrawalDelay WDelayerEventNewWithdrawalDelay
512			err := c.contractAbi.UnpackIntoInterface(&withdrawalDelay,
513				"NewWithdrawalDelay", vLog.Data)
514			if err != nil {
515				return nil, tracerr.Wrap(err)
516			}
517			wdelayerEvents.NewWithdrawalDelay =
518				append(wdelayerEvents.NewWithdrawalDelay, withdrawalDelay)
519
520		case logWDelayerEscapeHatchWithdrawal:
521			var escapeHatchWithdrawal WDelayerEventEscapeHatchWithdrawal
522			err := c.contractAbi.UnpackIntoInterface(&escapeHatchWithdrawal,
523				"EscapeHatchWithdrawal", vLog.Data)
524			if err != nil {
525				return nil, tracerr.Wrap(err)
526			}
527			escapeHatchWithdrawal.Who = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
528			escapeHatchWithdrawal.To = ethCommon.BytesToAddress(vLog.Topics[2].Bytes())
529			escapeHatchWithdrawal.Token = ethCommon.BytesToAddress(vLog.Topics[3].Bytes())
530			wdelayerEvents.EscapeHatchWithdrawal =
531				append(wdelayerEvents.EscapeHatchWithdrawal, escapeHatchWithdrawal)
532
533		case logWDelayerNewEmergencyCouncil:
534			var emergencyCouncil WDelayerEventNewEmergencyCouncil
535			err := c.contractAbi.UnpackIntoInterface(&emergencyCouncil,
536				"NewEmergencyCouncil", vLog.Data)
537			if err != nil {
538				return nil, tracerr.Wrap(err)
539			}
540			wdelayerEvents.NewEmergencyCouncil =
541				append(wdelayerEvents.NewEmergencyCouncil, emergencyCouncil)
542
543		case logWDelayerNewHermezGovernanceAddress:
544			var governanceAddress WDelayerEventNewHermezGovernanceAddress
545			err := c.contractAbi.UnpackIntoInterface(&governanceAddress,
546				"NewHermezGovernanceAddress", vLog.Data)
547			if err != nil {
548				return nil, tracerr.Wrap(err)
549			}
550			wdelayerEvents.NewHermezGovernanceAddress =
551				append(wdelayerEvents.NewHermezGovernanceAddress, governanceAddress)
552		}
553	}
554	return &wdelayerEvents, nil
555}