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.

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