You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

505 lines
19 KiB

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