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, amount *big.Int) (*types.Transaction, error)
136
137	WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, *ethCommon.Hash, error)
138	WDelayerConstants() (*common.WDelayerConstants, error)
139	WDelayerEventInit() (*WDelayerEventInitialize, int64, error)
140}
141
142//
143// Implementation
144//
145
146// WDelayerClient is the implementation of the interface to the WithdrawDelayer Smart Contract in ethereum.
147type WDelayerClient struct {
148	client      *EthereumClient
149	address     ethCommon.Address
150	wdelayer    *WithdrawalDelayer.WithdrawalDelayer
151	contractAbi abi.ABI
152	opts        *bind.CallOpts
153}
154
155// NewWDelayerClient creates a new WDelayerClient
156func NewWDelayerClient(client *EthereumClient, address ethCommon.Address) (*WDelayerClient, error) {
157	contractAbi, err := abi.JSON(strings.NewReader(string(WithdrawalDelayer.WithdrawalDelayerABI)))
158	if err != nil {
159		return nil, tracerr.Wrap(err)
160	}
161	wdelayer, err := WithdrawalDelayer.NewWithdrawalDelayer(address, client.Client())
162	if err != nil {
163		return nil, tracerr.Wrap(err)
164	}
165	return &WDelayerClient{
166		client:      client,
167		address:     address,
168		wdelayer:    wdelayer,
169		contractAbi: contractAbi,
170		opts:        newCallOpts(),
171	}, nil
172}
173
174// WDelayerGetHermezGovernanceAddress is the interface to call the smart contract function
175func (c *WDelayerClient) WDelayerGetHermezGovernanceAddress() (hermezGovernanceAddress *ethCommon.Address, err error) {
176	var _hermezGovernanceAddress ethCommon.Address
177	if err := c.client.Call(func(ec *ethclient.Client) error {
178		_hermezGovernanceAddress, err = c.wdelayer.GetHermezGovernanceAddress(c.opts)
179		return tracerr.Wrap(err)
180	}); err != nil {
181		return nil, tracerr.Wrap(err)
182	}
183	return &_hermezGovernanceAddress, nil
184}
185
186// WDelayerTransferGovernance is the interface to call the smart contract function
187func (c *WDelayerClient) WDelayerTransferGovernance(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
188	if tx, err = c.client.CallAuth(
189		0,
190		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
191			return c.wdelayer.TransferGovernance(auth, newAddress)
192		},
193	); err != nil {
194		return nil, tracerr.Wrap(fmt.Errorf("Failed transfer hermezGovernanceAddress: %w", err))
195	}
196	return tx, nil
197}
198
199// WDelayerClaimGovernance is the interface to call the smart contract function
200func (c *WDelayerClient) WDelayerClaimGovernance() (tx *types.Transaction, err error) {
201	if tx, err = c.client.CallAuth(
202		0,
203		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
204			return c.wdelayer.ClaimGovernance(auth)
205		},
206	); err != nil {
207		return nil, tracerr.Wrap(fmt.Errorf("Failed claim hermezGovernanceAddress: %w", err))
208	}
209	return tx, nil
210}
211
212// WDelayerGetEmergencyCouncil is the interface to call the smart contract function
213func (c *WDelayerClient) WDelayerGetEmergencyCouncil() (emergencyCouncilAddress *ethCommon.Address, err error) {
214	var _emergencyCouncilAddress ethCommon.Address
215	if err := c.client.Call(func(ec *ethclient.Client) error {
216		_emergencyCouncilAddress, err = c.wdelayer.GetEmergencyCouncil(c.opts)
217		return tracerr.Wrap(err)
218	}); err != nil {
219		return nil, tracerr.Wrap(err)
220	}
221	return &_emergencyCouncilAddress, nil
222}
223
224// WDelayerTransferEmergencyCouncil is the interface to call the smart contract function
225func (c *WDelayerClient) WDelayerTransferEmergencyCouncil(newAddress ethCommon.Address) (tx *types.Transaction, err error) {
226	if tx, err = c.client.CallAuth(
227		0,
228		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
229			return c.wdelayer.TransferEmergencyCouncil(auth, newAddress)
230		},
231	); err != nil {
232		return nil, tracerr.Wrap(fmt.Errorf("Failed transfer EmergencyCouncil: %w", err))
233	}
234	return tx, nil
235}
236
237// WDelayerClaimEmergencyCouncil is the interface to call the smart contract function
238func (c *WDelayerClient) WDelayerClaimEmergencyCouncil() (tx *types.Transaction, err error) {
239	if tx, err = c.client.CallAuth(
240		0,
241		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
242			return c.wdelayer.ClaimEmergencyCouncil(auth)
243		},
244	); err != nil {
245		return nil, tracerr.Wrap(fmt.Errorf("Failed claim EmergencyCouncil: %w", err))
246	}
247	return tx, nil
248}
249
250// WDelayerIsEmergencyMode is the interface to call the smart contract function
251func (c *WDelayerClient) WDelayerIsEmergencyMode() (ermergencyMode bool, err error) {
252	if err := c.client.Call(func(ec *ethclient.Client) error {
253		ermergencyMode, err = c.wdelayer.IsEmergencyMode(c.opts)
254		return tracerr.Wrap(err)
255	}); err != nil {
256		return false, tracerr.Wrap(err)
257	}
258	return ermergencyMode, nil
259}
260
261// WDelayerGetWithdrawalDelay is the interface to call the smart contract function
262func (c *WDelayerClient) WDelayerGetWithdrawalDelay() (withdrawalDelay int64, err error) {
263	var _withdrawalDelay uint64
264	if err := c.client.Call(func(ec *ethclient.Client) error {
265		_withdrawalDelay, err = c.wdelayer.GetWithdrawalDelay(c.opts)
266		return tracerr.Wrap(err)
267	}); err != nil {
268		return 0, tracerr.Wrap(err)
269	}
270	return int64(_withdrawalDelay), nil
271}
272
273// WDelayerGetEmergencyModeStartingTime is the interface to call the smart contract function
274func (c *WDelayerClient) WDelayerGetEmergencyModeStartingTime() (emergencyModeStartingTime int64, err error) {
275	var _emergencyModeStartingTime uint64
276	if err := c.client.Call(func(ec *ethclient.Client) error {
277		_emergencyModeStartingTime, err = c.wdelayer.GetEmergencyModeStartingTime(c.opts)
278		return tracerr.Wrap(err)
279	}); err != nil {
280		return 0, tracerr.Wrap(err)
281	}
282	return int64(_emergencyModeStartingTime), nil
283}
284
285// WDelayerEnableEmergencyMode is the interface to call the smart contract function
286func (c *WDelayerClient) WDelayerEnableEmergencyMode() (tx *types.Transaction, err error) {
287	if tx, err = c.client.CallAuth(
288		0,
289		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
290			return c.wdelayer.EnableEmergencyMode(auth)
291		},
292	); err != nil {
293		return nil, tracerr.Wrap(fmt.Errorf("Failed setting enable emergency mode: %w", err))
294	}
295	return tx, nil
296}
297
298// WDelayerChangeWithdrawalDelay is the interface to call the smart contract function
299func (c *WDelayerClient) WDelayerChangeWithdrawalDelay(newWithdrawalDelay uint64) (tx *types.Transaction, err error) {
300	if tx, err = c.client.CallAuth(
301		0,
302		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
303			return c.wdelayer.ChangeWithdrawalDelay(auth, newWithdrawalDelay)
304		},
305	); err != nil {
306		return nil, tracerr.Wrap(fmt.Errorf("Failed setting withdrawal delay: %w", err))
307	}
308	return tx, nil
309}
310
311// WDelayerDepositInfo is the interface to call the smart contract function
312func (c *WDelayerClient) WDelayerDepositInfo(owner, token ethCommon.Address) (depositInfo DepositState, err error) {
313	if err := c.client.Call(func(ec *ethclient.Client) error {
314		amount, depositTimestamp, err := c.wdelayer.DepositInfo(c.opts, owner, token)
315		depositInfo.Amount = amount
316		depositInfo.DepositTimestamp = depositTimestamp
317		return tracerr.Wrap(err)
318	}); err != nil {
319		return depositInfo, tracerr.Wrap(err)
320	}
321	return depositInfo, nil
322}
323
324// WDelayerDeposit is the interface to call the smart contract function
325func (c *WDelayerClient) WDelayerDeposit(owner, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
326	if tx, err = c.client.CallAuth(
327		0,
328		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
329			return c.wdelayer.Deposit(auth, owner, token, amount)
330		},
331	); err != nil {
332		return nil, tracerr.Wrap(fmt.Errorf("Failed deposit: %w", err))
333	}
334	return tx, nil
335}
336
337// WDelayerWithdrawal is the interface to call the smart contract function
338func (c *WDelayerClient) WDelayerWithdrawal(owner, token ethCommon.Address) (tx *types.Transaction, err error) {
339	if tx, err = c.client.CallAuth(
340		0,
341		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
342			return c.wdelayer.Withdrawal(auth, owner, token)
343		},
344	); err != nil {
345		return nil, tracerr.Wrap(fmt.Errorf("Failed withdrawal: %w", err))
346	}
347	return tx, nil
348}
349
350// WDelayerEscapeHatchWithdrawal is the interface to call the smart contract function
351func (c *WDelayerClient) WDelayerEscapeHatchWithdrawal(to, token ethCommon.Address, amount *big.Int) (tx *types.Transaction, err error) {
352	if tx, err = c.client.CallAuth(
353		0,
354		func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
355			return c.wdelayer.EscapeHatchWithdrawal(auth, to, token, amount)
356		},
357	); err != nil {
358		return nil, tracerr.Wrap(fmt.Errorf("Failed escapeHatchWithdrawal: %w", err))
359	}
360	return tx, nil
361}
362
363// WDelayerConstants returns the Constants of the WDelayer Smart Contract
364func (c *WDelayerClient) WDelayerConstants() (constants *common.WDelayerConstants, err error) {
365	constants = new(common.WDelayerConstants)
366	if err := c.client.Call(func(ec *ethclient.Client) error {
367		constants.MaxWithdrawalDelay, err = c.wdelayer.MAXWITHDRAWALDELAY(c.opts)
368		if err != nil {
369			return tracerr.Wrap(err)
370		}
371		constants.MaxEmergencyModeTime, err = c.wdelayer.MAXEMERGENCYMODETIME(c.opts)
372		if err != nil {
373			return tracerr.Wrap(err)
374		}
375		constants.HermezRollup, err = c.wdelayer.HermezRollupAddress(c.opts)
376		if err != nil {
377			return tracerr.Wrap(err)
378		}
379		return tracerr.Wrap(err)
380	}); err != nil {
381		return constants, tracerr.Wrap(err)
382	}
383	return constants, nil
384}
385
386var (
387	logWDelayerDeposit                    = crypto.Keccak256Hash([]byte("Deposit(address,address,uint192,uint64)"))
388	logWDelayerWithdraw                   = crypto.Keccak256Hash([]byte("Withdraw(address,address,uint192)"))
389	logWDelayerEmergencyModeEnabled       = crypto.Keccak256Hash([]byte("EmergencyModeEnabled()"))
390	logWDelayerNewWithdrawalDelay         = crypto.Keccak256Hash([]byte("NewWithdrawalDelay(uint64)"))
391	logWDelayerEscapeHatchWithdrawal      = crypto.Keccak256Hash([]byte("EscapeHatchWithdrawal(address,address,address,uint256)"))
392	logWDelayerNewEmergencyCouncil        = crypto.Keccak256Hash([]byte("NewEmergencyCouncil(address)"))
393	logWDelayerNewHermezGovernanceAddress = crypto.Keccak256Hash([]byte("NewHermezGovernanceAddress(address)"))
394	logWDelayerInitialize                 = crypto.Keccak256Hash([]byte(
395		"InitializeWithdrawalDelayerEvent(uint64,address,address)"))
396)
397
398// WDelayerEventInit returns the initialize event with its corresponding block number
399func (c *WDelayerClient) WDelayerEventInit() (*WDelayerEventInitialize, int64, error) {
400	query := ethereum.FilterQuery{
401		Addresses: []ethCommon.Address{
402			c.address,
403		},
404		Topics: [][]ethCommon.Hash{{logWDelayerInitialize}},
405	}
406	logs, err := c.client.client.FilterLogs(context.Background(), query)
407	if err != nil {
408		return nil, 0, tracerr.Wrap(err)
409	}
410	if len(logs) != 1 {
411		return nil, 0, tracerr.Wrap(fmt.Errorf("no event of type InitializeWithdrawalDelayerEvent found"))
412	}
413	vLog := logs[0]
414	if vLog.Topics[0] != logWDelayerInitialize {
415		return nil, 0, tracerr.Wrap(fmt.Errorf("event is not InitializeWithdrawalDelayerEvent"))
416	}
417
418	var wDelayerInit WDelayerEventInitialize
419	if err := c.contractAbi.UnpackIntoInterface(&wDelayerInit, "InitializeWithdrawalDelayerEvent",
420		vLog.Data); err != nil {
421		return nil, 0, tracerr.Wrap(err)
422	}
423	return &wDelayerInit, int64(vLog.BlockNumber), tracerr.Wrap(err)
424}
425
426// WDelayerEventsByBlock returns the events in a block that happened in the
427// WDelayer Smart Contract and the blockHash where the eents happened.  If
428// there are no events in that block, blockHash is nil.
429func (c *WDelayerClient) WDelayerEventsByBlock(blockNum int64) (*WDelayerEvents, *ethCommon.Hash, error) {
430	var wdelayerEvents WDelayerEvents
431	var blockHash *ethCommon.Hash
432
433	query := ethereum.FilterQuery{
434		FromBlock: big.NewInt(blockNum),
435		ToBlock:   big.NewInt(blockNum),
436		Addresses: []ethCommon.Address{
437			c.address,
438		},
439		BlockHash: nil,
440		Topics:    [][]ethCommon.Hash{},
441	}
442
443	logs, err := c.client.client.FilterLogs(context.Background(), query)
444	if err != nil {
445		return nil, nil, tracerr.Wrap(err)
446	}
447	if len(logs) > 0 {
448		blockHash = &logs[0].BlockHash
449	}
450	for _, vLog := range logs {
451		if vLog.BlockHash != *blockHash {
452			log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String())
453			return nil, nil, tracerr.Wrap(ErrBlockHashMismatchEvent)
454		}
455		switch vLog.Topics[0] {
456		case logWDelayerDeposit:
457			var deposit WDelayerEventDeposit
458			err := c.contractAbi.UnpackIntoInterface(&deposit, "Deposit", vLog.Data)
459			if err != nil {
460				return nil, nil, tracerr.Wrap(err)
461			}
462			deposit.Owner = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
463			deposit.Token = ethCommon.BytesToAddress(vLog.Topics[2].Bytes())
464			deposit.TxHash = vLog.TxHash
465			wdelayerEvents.Deposit = append(wdelayerEvents.Deposit, deposit)
466
467		case logWDelayerWithdraw:
468			var withdraw WDelayerEventWithdraw
469			err := c.contractAbi.UnpackIntoInterface(&withdraw, "Withdraw", vLog.Data)
470			if err != nil {
471				return nil, nil, tracerr.Wrap(err)
472			}
473			withdraw.Token = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
474			withdraw.Owner = ethCommon.BytesToAddress(vLog.Topics[2].Bytes())
475			wdelayerEvents.Withdraw = append(wdelayerEvents.Withdraw, withdraw)
476
477		case logWDelayerEmergencyModeEnabled:
478			var emergencyModeEnabled WDelayerEventEmergencyModeEnabled
479			wdelayerEvents.EmergencyModeEnabled = append(wdelayerEvents.EmergencyModeEnabled, emergencyModeEnabled)
480
481		case logWDelayerNewWithdrawalDelay:
482			var withdrawalDelay WDelayerEventNewWithdrawalDelay
483			err := c.contractAbi.UnpackIntoInterface(&withdrawalDelay, "NewWithdrawalDelay", vLog.Data)
484			if err != nil {
485				return nil, nil, tracerr.Wrap(err)
486			}
487			wdelayerEvents.NewWithdrawalDelay = append(wdelayerEvents.NewWithdrawalDelay, withdrawalDelay)
488
489		case logWDelayerEscapeHatchWithdrawal:
490			var escapeHatchWithdrawal WDelayerEventEscapeHatchWithdrawal
491			err := c.contractAbi.UnpackIntoInterface(&escapeHatchWithdrawal, "EscapeHatchWithdrawal", vLog.Data)
492			if err != nil {
493				return nil, nil, tracerr.Wrap(err)
494			}
495			escapeHatchWithdrawal.Who = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
496			escapeHatchWithdrawal.To = ethCommon.BytesToAddress(vLog.Topics[2].Bytes())
497			escapeHatchWithdrawal.Token = ethCommon.BytesToAddress(vLog.Topics[3].Bytes())
498			wdelayerEvents.EscapeHatchWithdrawal = append(wdelayerEvents.EscapeHatchWithdrawal, escapeHatchWithdrawal)
499
500		case logWDelayerNewEmergencyCouncil:
501			var emergencyCouncil WDelayerEventNewEmergencyCouncil
502			err := c.contractAbi.UnpackIntoInterface(&emergencyCouncil, "NewEmergencyCouncil", vLog.Data)
503			if err != nil {
504				return nil, nil, tracerr.Wrap(err)
505			}
506			wdelayerEvents.NewEmergencyCouncil = append(wdelayerEvents.NewEmergencyCouncil, emergencyCouncil)
507
508		case logWDelayerNewHermezGovernanceAddress:
509			var governanceAddress WDelayerEventNewHermezGovernanceAddress
510			err := c.contractAbi.UnpackIntoInterface(&governanceAddress, "NewHermezGovernanceAddress", vLog.Data)
511			if err != nil {
512				return nil, nil, tracerr.Wrap(err)
513			}
514			wdelayerEvents.NewHermezGovernanceAddress = append(wdelayerEvents.NewHermezGovernanceAddress, governanceAddress)
515		}
516	}
517	return &wdelayerEvents, blockHash, nil
518}