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