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.

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