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.

996 lines
38 KiB

4 years ago
  1. package eth
  2. import (
  3. "context"
  4. "fmt"
  5. "math/big"
  6. "strconv"
  7. "strings"
  8. "github.com/ethereum/go-ethereum"
  9. "github.com/ethereum/go-ethereum/accounts/abi"
  10. "github.com/ethereum/go-ethereum/accounts/abi/bind"
  11. ethCommon "github.com/ethereum/go-ethereum/common"
  12. "github.com/ethereum/go-ethereum/core/types"
  13. "github.com/ethereum/go-ethereum/crypto"
  14. "github.com/ethereum/go-ethereum/ethclient"
  15. "github.com/hermeznetwork/hermez-node/common"
  16. Hermez "github.com/hermeznetwork/hermez-node/eth/contracts/hermez"
  17. HEZ "github.com/hermeznetwork/hermez-node/eth/contracts/tokenHEZ"
  18. "github.com/hermeznetwork/hermez-node/log"
  19. "github.com/hermeznetwork/tracerr"
  20. "github.com/iden3/go-iden3-crypto/babyjub"
  21. )
  22. // QueueStruct is the queue of L1Txs for a batch
  23. type QueueStruct struct {
  24. L1TxQueue []common.L1Tx
  25. TotalL1TxFee *big.Int
  26. }
  27. // NewQueueStruct creates a new clear QueueStruct.
  28. func NewQueueStruct() *QueueStruct {
  29. return &QueueStruct{
  30. L1TxQueue: make([]common.L1Tx, 0),
  31. TotalL1TxFee: big.NewInt(0),
  32. }
  33. }
  34. // RollupState represents the state of the Rollup in the Smart Contract
  35. type RollupState struct {
  36. StateRoot *big.Int
  37. ExitRoots []*big.Int
  38. // ExitNullifierMap map[[256 / 8]byte]bool
  39. ExitNullifierMap map[int64]map[int64]bool // batchNum -> idx -> bool
  40. TokenList []ethCommon.Address
  41. TokenMap map[ethCommon.Address]bool
  42. MapL1TxQueue map[int64]*QueueStruct
  43. LastL1L2Batch int64
  44. CurrentToForgeL1TxsNum int64
  45. LastToForgeL1TxsNum int64
  46. CurrentIdx int64
  47. }
  48. // RollupEventInitialize is the InitializeHermezEvent event of the
  49. // Smart Contract
  50. type RollupEventInitialize struct {
  51. ForgeL1L2BatchTimeout uint8
  52. FeeAddToken *big.Int
  53. WithdrawalDelay uint64
  54. }
  55. // RollupVariables returns the RollupVariables from the initialize event
  56. func (ei *RollupEventInitialize) RollupVariables() *common.RollupVariables {
  57. var buckets [common.RollupConstNumBuckets]common.BucketParams
  58. for i := range buckets {
  59. buckets[i] = common.BucketParams{
  60. CeilUSD: big.NewInt(0),
  61. Withdrawals: big.NewInt(0),
  62. BlockWithdrawalRate: big.NewInt(0),
  63. MaxWithdrawals: big.NewInt(0),
  64. }
  65. }
  66. return &common.RollupVariables{
  67. EthBlockNum: 0,
  68. FeeAddToken: ei.FeeAddToken,
  69. ForgeL1L2BatchTimeout: int64(ei.ForgeL1L2BatchTimeout),
  70. WithdrawalDelay: ei.WithdrawalDelay,
  71. Buckets: buckets,
  72. SafeMode: false,
  73. }
  74. }
  75. // RollupEventL1UserTx is an event of the Rollup Smart Contract
  76. type RollupEventL1UserTx struct {
  77. // ToForgeL1TxsNum int64 // QueueIndex *big.Int
  78. // Position int // TransactionIndex *big.Int
  79. L1UserTx common.L1Tx
  80. }
  81. // RollupEventL1UserTxAux is an event of the Rollup Smart Contract
  82. type rollupEventL1UserTxAux struct {
  83. ToForgeL1TxsNum uint64 // QueueIndex *big.Int
  84. Position uint8 // TransactionIndex *big.Int
  85. L1UserTx []byte
  86. }
  87. // RollupEventAddToken is an event of the Rollup Smart Contract
  88. type RollupEventAddToken struct {
  89. TokenAddress ethCommon.Address
  90. TokenID uint32
  91. }
  92. // RollupEventForgeBatch is an event of the Rollup Smart Contract
  93. type RollupEventForgeBatch struct {
  94. BatchNum int64
  95. // Sender ethCommon.Address
  96. EthTxHash ethCommon.Hash
  97. L1UserTxsLen uint16
  98. }
  99. // RollupEventUpdateForgeL1L2BatchTimeout is an event of the Rollup Smart Contract
  100. type RollupEventUpdateForgeL1L2BatchTimeout struct {
  101. NewForgeL1L2BatchTimeout int64
  102. }
  103. // RollupEventUpdateFeeAddToken is an event of the Rollup Smart Contract
  104. type RollupEventUpdateFeeAddToken struct {
  105. NewFeeAddToken *big.Int
  106. }
  107. // RollupEventWithdraw is an event of the Rollup Smart Contract
  108. type RollupEventWithdraw struct {
  109. Idx uint64
  110. NumExitRoot uint64
  111. InstantWithdraw bool
  112. TxHash ethCommon.Hash // Hash of the transaction that generated this event
  113. }
  114. type rollupEventUpdateBucketWithdrawAux struct {
  115. NumBucket uint8
  116. BlockStamp *big.Int
  117. Withdrawals *big.Int
  118. }
  119. // RollupEventUpdateBucketWithdraw is an event of the Rollup Smart Contract
  120. type RollupEventUpdateBucketWithdraw struct {
  121. NumBucket int
  122. BlockStamp int64 // blockNum
  123. Withdrawals *big.Int
  124. }
  125. // RollupEventUpdateWithdrawalDelay is an event of the Rollup Smart Contract
  126. type RollupEventUpdateWithdrawalDelay struct {
  127. NewWithdrawalDelay uint64
  128. }
  129. // RollupUpdateBucketsParameters are the bucket parameters used in an update
  130. type RollupUpdateBucketsParameters struct {
  131. CeilUSD *big.Int
  132. Withdrawals *big.Int
  133. BlockWithdrawalRate *big.Int
  134. MaxWithdrawals *big.Int
  135. }
  136. type rollupEventUpdateBucketsParametersAux struct {
  137. ArrayBuckets [common.RollupConstNumBuckets][4]*big.Int
  138. }
  139. // RollupEventUpdateBucketsParameters is an event of the Rollup Smart Contract
  140. type RollupEventUpdateBucketsParameters struct {
  141. // ArrayBuckets [common.RollupConstNumBuckets][4]*big.Int
  142. ArrayBuckets [common.RollupConstNumBuckets]RollupUpdateBucketsParameters
  143. SafeMode bool
  144. }
  145. // RollupEventUpdateTokenExchange is an event of the Rollup Smart Contract
  146. type RollupEventUpdateTokenExchange struct {
  147. AddressArray []ethCommon.Address
  148. ValueArray []uint64
  149. }
  150. // RollupEventSafeMode is an event of the Rollup Smart Contract
  151. type RollupEventSafeMode struct {
  152. }
  153. // RollupEvents is the list of events in a block of the Rollup Smart Contract
  154. type RollupEvents struct {
  155. L1UserTx []RollupEventL1UserTx
  156. AddToken []RollupEventAddToken
  157. ForgeBatch []RollupEventForgeBatch
  158. UpdateForgeL1L2BatchTimeout []RollupEventUpdateForgeL1L2BatchTimeout
  159. UpdateFeeAddToken []RollupEventUpdateFeeAddToken
  160. Withdraw []RollupEventWithdraw
  161. UpdateWithdrawalDelay []RollupEventUpdateWithdrawalDelay
  162. UpdateBucketWithdraw []RollupEventUpdateBucketWithdraw
  163. UpdateBucketsParameters []RollupEventUpdateBucketsParameters
  164. UpdateTokenExchange []RollupEventUpdateTokenExchange
  165. SafeMode []RollupEventSafeMode
  166. }
  167. // NewRollupEvents creates an empty RollupEvents with the slices initialized.
  168. func NewRollupEvents() RollupEvents {
  169. return RollupEvents{
  170. L1UserTx: make([]RollupEventL1UserTx, 0),
  171. AddToken: make([]RollupEventAddToken, 0),
  172. ForgeBatch: make([]RollupEventForgeBatch, 0),
  173. UpdateForgeL1L2BatchTimeout: make([]RollupEventUpdateForgeL1L2BatchTimeout, 0),
  174. UpdateFeeAddToken: make([]RollupEventUpdateFeeAddToken, 0),
  175. Withdraw: make([]RollupEventWithdraw, 0),
  176. }
  177. }
  178. // RollupForgeBatchArgs are the arguments to the ForgeBatch function in the Rollup Smart Contract
  179. type RollupForgeBatchArgs struct {
  180. NewLastIdx int64
  181. NewStRoot *big.Int
  182. NewExitRoot *big.Int
  183. L1UserTxs []common.L1Tx
  184. L1CoordinatorTxs []common.L1Tx
  185. L1CoordinatorTxsAuths [][]byte // Authorization for accountCreations for each L1CoordinatorTx
  186. L2TxsData []common.L2Tx
  187. FeeIdxCoordinator []common.Idx
  188. // Circuit selector
  189. VerifierIdx uint8
  190. L1Batch bool
  191. ProofA [2]*big.Int
  192. ProofB [2][2]*big.Int
  193. ProofC [2]*big.Int
  194. }
  195. // RollupForgeBatchArgsAux are the arguments to the ForgeBatch function in the Rollup Smart Contract
  196. type rollupForgeBatchArgsAux struct {
  197. NewLastIdx *big.Int
  198. NewStRoot *big.Int
  199. NewExitRoot *big.Int
  200. EncodedL1CoordinatorTx []byte
  201. L1L2TxsData []byte
  202. FeeIdxCoordinator []byte
  203. // Circuit selector
  204. VerifierIdx uint8
  205. L1Batch bool
  206. ProofA [2]*big.Int
  207. ProofB [2][2]*big.Int
  208. ProofC [2]*big.Int
  209. }
  210. // RollupInterface is the inteface to to Rollup Smart Contract
  211. type RollupInterface interface {
  212. //
  213. // Smart Contract Methods
  214. //
  215. // Public Functions
  216. RollupForgeBatch(*RollupForgeBatchArgs, *bind.TransactOpts) (*types.Transaction, error)
  217. RollupAddToken(tokenAddress ethCommon.Address, feeAddToken, deadline *big.Int) (*types.Transaction, error)
  218. RollupWithdrawMerkleProof(babyPubKey babyjub.PublicKeyComp, tokenID uint32, numExitRoot, idx int64, amount *big.Int, siblings []*big.Int, instantWithdraw bool) (*types.Transaction, error)
  219. RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int, tokenID uint32, numExitRoot, idx int64, amount *big.Int, instantWithdraw bool) (*types.Transaction, error)
  220. RollupL1UserTxERC20ETH(fromBJJ babyjub.PublicKeyComp, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (*types.Transaction, error)
  221. RollupL1UserTxERC20Permit(fromBJJ babyjub.PublicKeyComp, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64, deadline *big.Int) (tx *types.Transaction, err error)
  222. // Governance Public Functions
  223. RollupUpdateForgeL1L2BatchTimeout(newForgeL1L2BatchTimeout int64) (*types.Transaction, error)
  224. RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error)
  225. // Viewers
  226. RollupRegisterTokensCount() (*big.Int, error)
  227. RollupLastForgedBatch() (int64, error)
  228. //
  229. // Smart Contract Status
  230. //
  231. RollupConstants() (*common.RollupConstants, error)
  232. RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error)
  233. RollupForgeBatchArgs(ethCommon.Hash, uint16) (*RollupForgeBatchArgs, *ethCommon.Address, error)
  234. RollupEventInit() (*RollupEventInitialize, int64, error)
  235. }
  236. //
  237. // Implementation
  238. //
  239. // RollupClient is the implementation of the interface to the Rollup Smart Contract in ethereum.
  240. type RollupClient struct {
  241. client *EthereumClient
  242. chainID *big.Int
  243. address ethCommon.Address
  244. tokenHEZCfg TokenConfig
  245. hermez *Hermez.Hermez
  246. tokenHEZ *HEZ.HEZ
  247. contractAbi abi.ABI
  248. opts *bind.CallOpts
  249. consts *common.RollupConstants
  250. }
  251. // NewRollupClient creates a new RollupClient
  252. func NewRollupClient(client *EthereumClient, address ethCommon.Address, tokenHEZCfg TokenConfig) (*RollupClient, error) {
  253. contractAbi, err := abi.JSON(strings.NewReader(string(Hermez.HermezABI)))
  254. if err != nil {
  255. return nil, tracerr.Wrap(err)
  256. }
  257. hermez, err := Hermez.NewHermez(address, client.Client())
  258. if err != nil {
  259. return nil, tracerr.Wrap(err)
  260. }
  261. tokenHEZ, err := HEZ.NewHEZ(tokenHEZCfg.Address, client.Client())
  262. if err != nil {
  263. return nil, tracerr.Wrap(err)
  264. }
  265. chainID, err := client.EthChainID()
  266. if err != nil {
  267. return nil, tracerr.Wrap(err)
  268. }
  269. c := &RollupClient{
  270. client: client,
  271. chainID: chainID,
  272. address: address,
  273. tokenHEZCfg: tokenHEZCfg,
  274. hermez: hermez,
  275. tokenHEZ: tokenHEZ,
  276. contractAbi: contractAbi,
  277. opts: newCallOpts(),
  278. }
  279. consts, err := c.RollupConstants()
  280. if err != nil {
  281. return nil, tracerr.Wrap(err)
  282. }
  283. c.consts = consts
  284. return c, nil
  285. }
  286. // RollupForgeBatch is the interface to call the smart contract function
  287. func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs, auth *bind.TransactOpts) (tx *types.Transaction, err error) {
  288. if auth == nil {
  289. auth, err = c.client.NewAuth()
  290. if err != nil {
  291. return nil, err
  292. }
  293. auth.GasLimit = 1000000
  294. }
  295. nLevels := c.consts.Verifiers[args.VerifierIdx].NLevels
  296. lenBytes := nLevels / 8 //nolint:gomnd
  297. newLastIdx := big.NewInt(int64(args.NewLastIdx))
  298. // L1CoordinatorBytes
  299. var l1CoordinatorBytes []byte
  300. for i := 0; i < len(args.L1CoordinatorTxs); i++ {
  301. l1 := args.L1CoordinatorTxs[i]
  302. bytesl1, err := l1.BytesCoordinatorTx(args.L1CoordinatorTxsAuths[i])
  303. if err != nil {
  304. return nil, tracerr.Wrap(err)
  305. }
  306. l1CoordinatorBytes = append(l1CoordinatorBytes, bytesl1[:]...)
  307. }
  308. // L1L2TxData
  309. var l1l2TxData []byte
  310. for i := 0; i < len(args.L1UserTxs); i++ {
  311. l1User := args.L1UserTxs[i]
  312. bytesl1User, err := l1User.BytesDataAvailability(uint32(nLevels))
  313. if err != nil {
  314. return nil, tracerr.Wrap(err)
  315. }
  316. l1l2TxData = append(l1l2TxData, bytesl1User[:]...)
  317. }
  318. for i := 0; i < len(args.L1CoordinatorTxs); i++ {
  319. l1Coord := args.L1CoordinatorTxs[i]
  320. bytesl1Coord, err := l1Coord.BytesDataAvailability(uint32(nLevels))
  321. if err != nil {
  322. return nil, tracerr.Wrap(err)
  323. }
  324. l1l2TxData = append(l1l2TxData, bytesl1Coord[:]...)
  325. }
  326. for i := 0; i < len(args.L2TxsData); i++ {
  327. l2 := args.L2TxsData[i]
  328. bytesl2, err := l2.BytesDataAvailability(uint32(nLevels))
  329. if err != nil {
  330. return nil, tracerr.Wrap(err)
  331. }
  332. l1l2TxData = append(l1l2TxData, bytesl2[:]...)
  333. }
  334. // FeeIdxCoordinator
  335. var feeIdxCoordinator []byte
  336. if len(args.FeeIdxCoordinator) > common.RollupConstMaxFeeIdxCoordinator {
  337. return nil, tracerr.Wrap(fmt.Errorf("len(args.FeeIdxCoordinator) > %v",
  338. common.RollupConstMaxFeeIdxCoordinator))
  339. }
  340. for i := 0; i < common.RollupConstMaxFeeIdxCoordinator; i++ {
  341. feeIdx := common.Idx(0)
  342. if i < len(args.FeeIdxCoordinator) {
  343. feeIdx = args.FeeIdxCoordinator[i]
  344. }
  345. bytesFeeIdx, err := feeIdx.Bytes()
  346. if err != nil {
  347. return nil, tracerr.Wrap(err)
  348. }
  349. feeIdxCoordinator = append(feeIdxCoordinator,
  350. bytesFeeIdx[len(bytesFeeIdx)-int(lenBytes):]...)
  351. }
  352. tx, err = c.hermez.ForgeBatch(auth, newLastIdx, args.NewStRoot, args.NewExitRoot,
  353. l1CoordinatorBytes, l1l2TxData, feeIdxCoordinator, args.VerifierIdx, args.L1Batch,
  354. args.ProofA, args.ProofB, args.ProofC)
  355. if err != nil {
  356. return nil, tracerr.Wrap(fmt.Errorf("Failed Hermez.ForgeBatch: %w", err))
  357. }
  358. return tx, nil
  359. }
  360. // RollupAddToken is the interface to call the smart contract function.
  361. // `feeAddToken` is the amount of HEZ tokens that will be paid to add the
  362. // token. `feeAddToken` must match the public value of the smart contract.
  363. func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address, feeAddToken, deadline *big.Int) (tx *types.Transaction, err error) {
  364. if tx, err = c.client.CallAuth(
  365. 0,
  366. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  367. owner := c.client.account.Address
  368. spender := c.address
  369. nonce, err := c.tokenHEZ.Nonces(c.opts, owner)
  370. if err != nil {
  371. return nil, tracerr.Wrap(err)
  372. }
  373. tokenName := c.tokenHEZCfg.Name
  374. tokenAddr := c.tokenHEZCfg.Address
  375. digest, _ := createPermitDigest(tokenAddr, owner, spender, c.chainID, feeAddToken, nonce, deadline, tokenName)
  376. signature, _ := c.client.ks.SignHash(*c.client.account, digest)
  377. permit := createPermit(owner, spender, feeAddToken, deadline, digest, signature)
  378. return c.hermez.AddToken(auth, tokenAddress, permit)
  379. },
  380. ); err != nil {
  381. return nil, tracerr.Wrap(fmt.Errorf("Failed add Token %w", err))
  382. }
  383. return tx, nil
  384. }
  385. // RollupWithdrawMerkleProof is the interface to call the smart contract function
  386. func (c *RollupClient) RollupWithdrawMerkleProof(fromBJJ babyjub.PublicKeyComp, tokenID uint32, numExitRoot, idx int64, amount *big.Int, siblings []*big.Int, instantWithdraw bool) (tx *types.Transaction, err error) {
  387. if tx, err = c.client.CallAuth(
  388. 0,
  389. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  390. pkCompB := common.SwapEndianness(fromBJJ[:])
  391. babyPubKey := new(big.Int).SetBytes(pkCompB)
  392. numExitRootB := uint32(numExitRoot)
  393. idxBig := big.NewInt(idx)
  394. return c.hermez.WithdrawMerkleProof(auth, tokenID, amount, babyPubKey, numExitRootB, siblings, idxBig, instantWithdraw)
  395. },
  396. ); err != nil {
  397. return nil, tracerr.Wrap(fmt.Errorf("Failed update WithdrawMerkleProof: %w", err))
  398. }
  399. return tx, nil
  400. }
  401. // RollupWithdrawCircuit is the interface to call the smart contract function
  402. func (c *RollupClient) RollupWithdrawCircuit(proofA, proofC [2]*big.Int, proofB [2][2]*big.Int, tokenID uint32, numExitRoot, idx int64, amount *big.Int, instantWithdraw bool) (*types.Transaction, error) {
  403. log.Error("TODO")
  404. return nil, tracerr.Wrap(errTODO)
  405. }
  406. // RollupL1UserTxERC20ETH is the interface to call the smart contract function
  407. func (c *RollupClient) RollupL1UserTxERC20ETH(fromBJJ babyjub.PublicKeyComp, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64) (tx *types.Transaction, err error) {
  408. if tx, err = c.client.CallAuth(
  409. 0,
  410. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  411. var babyPubKey *big.Int
  412. if fromBJJ != common.EmptyBJJComp {
  413. pkCompB := common.SwapEndianness(fromBJJ[:])
  414. babyPubKey = new(big.Int).SetBytes(pkCompB)
  415. } else {
  416. babyPubKey = big.NewInt(0)
  417. }
  418. fromIdxBig := big.NewInt(fromIdx)
  419. toIdxBig := big.NewInt(toIdx)
  420. depositAmountF, err := common.NewFloat16(depositAmount)
  421. if err != nil {
  422. return nil, tracerr.Wrap(err)
  423. }
  424. amountF, err := common.NewFloat16(amount)
  425. if err != nil {
  426. return nil, tracerr.Wrap(err)
  427. }
  428. if tokenID == 0 {
  429. auth.Value = depositAmount
  430. }
  431. var permit []byte
  432. return c.hermez.AddL1Transaction(auth, babyPubKey, fromIdxBig, uint16(depositAmountF),
  433. uint16(amountF), tokenID, toIdxBig, permit)
  434. },
  435. ); err != nil {
  436. return nil, tracerr.Wrap(fmt.Errorf("Failed add L1 Tx ERC20/ETH: %w", err))
  437. }
  438. return tx, nil
  439. }
  440. // RollupL1UserTxERC20Permit is the interface to call the smart contract function
  441. func (c *RollupClient) RollupL1UserTxERC20Permit(fromBJJ babyjub.PublicKeyComp, fromIdx int64, depositAmount *big.Int, amount *big.Int, tokenID uint32, toIdx int64, deadline *big.Int) (tx *types.Transaction, err error) {
  442. if tx, err = c.client.CallAuth(
  443. 0,
  444. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  445. var babyPubKey *big.Int
  446. if fromBJJ != common.EmptyBJJComp {
  447. pkCompB := common.SwapEndianness(fromBJJ[:])
  448. babyPubKey = new(big.Int).SetBytes(pkCompB)
  449. } else {
  450. babyPubKey = big.NewInt(0)
  451. }
  452. fromIdxBig := big.NewInt(fromIdx)
  453. toIdxBig := big.NewInt(toIdx)
  454. depositAmountF, err := common.NewFloat16(depositAmount)
  455. if err != nil {
  456. return nil, tracerr.Wrap(err)
  457. }
  458. amountF, err := common.NewFloat16(amount)
  459. if err != nil {
  460. return nil, tracerr.Wrap(err)
  461. }
  462. if tokenID == 0 {
  463. auth.Value = depositAmount
  464. }
  465. owner := c.client.account.Address
  466. spender := c.address
  467. nonce, err := c.tokenHEZ.Nonces(c.opts, owner)
  468. if err != nil {
  469. return nil, tracerr.Wrap(err)
  470. }
  471. tokenName := c.tokenHEZCfg.Name
  472. tokenAddr := c.tokenHEZCfg.Address
  473. digest, _ := createPermitDigest(tokenAddr, owner, spender, c.chainID, amount, nonce, deadline, tokenName)
  474. signature, _ := c.client.ks.SignHash(*c.client.account, digest)
  475. permit := createPermit(owner, spender, amount, deadline, digest, signature)
  476. return c.hermez.AddL1Transaction(auth, babyPubKey, fromIdxBig, uint16(depositAmountF),
  477. uint16(amountF), tokenID, toIdxBig, permit)
  478. },
  479. ); err != nil {
  480. return nil, tracerr.Wrap(fmt.Errorf("Failed add L1 Tx ERC20Permit: %w", err))
  481. }
  482. return tx, nil
  483. }
  484. // RollupRegisterTokensCount is the interface to call the smart contract function
  485. func (c *RollupClient) RollupRegisterTokensCount() (registerTokensCount *big.Int, err error) {
  486. if err := c.client.Call(func(ec *ethclient.Client) error {
  487. registerTokensCount, err = c.hermez.RegisterTokensCount(c.opts)
  488. return tracerr.Wrap(err)
  489. }); err != nil {
  490. return nil, tracerr.Wrap(err)
  491. }
  492. return registerTokensCount, nil
  493. }
  494. // RollupLastForgedBatch is the interface to call the smart contract function
  495. func (c *RollupClient) RollupLastForgedBatch() (lastForgedBatch int64, err error) {
  496. if err := c.client.Call(func(ec *ethclient.Client) error {
  497. _lastForgedBatch, err := c.hermez.LastForgedBatch(c.opts)
  498. lastForgedBatch = int64(_lastForgedBatch)
  499. return tracerr.Wrap(err)
  500. }); err != nil {
  501. return 0, tracerr.Wrap(err)
  502. }
  503. return lastForgedBatch, nil
  504. }
  505. // RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
  506. func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1L2BatchTimeout int64) (tx *types.Transaction, err error) {
  507. if tx, err = c.client.CallAuth(
  508. 0,
  509. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  510. return c.hermez.UpdateForgeL1L2BatchTimeout(auth, uint8(newForgeL1L2BatchTimeout))
  511. },
  512. ); err != nil {
  513. return nil, tracerr.Wrap(fmt.Errorf("Failed update ForgeL1L2BatchTimeout: %w", err))
  514. }
  515. return tx, nil
  516. }
  517. // RollupUpdateFeeAddToken is the interface to call the smart contract function
  518. func (c *RollupClient) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (tx *types.Transaction, err error) {
  519. if tx, err = c.client.CallAuth(
  520. 0,
  521. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  522. return c.hermez.UpdateFeeAddToken(auth, newFeeAddToken)
  523. },
  524. ); err != nil {
  525. return nil, tracerr.Wrap(fmt.Errorf("Failed update FeeAddToken: %w", err))
  526. }
  527. return tx, nil
  528. }
  529. // RollupUpdateBucketsParameters is the interface to call the smart contract function
  530. func (c *RollupClient) RollupUpdateBucketsParameters(
  531. arrayBuckets [common.RollupConstNumBuckets]RollupUpdateBucketsParameters,
  532. ) (tx *types.Transaction, err error) {
  533. params := [common.RollupConstNumBuckets][4]*big.Int{}
  534. for i, bucket := range arrayBuckets {
  535. params[i][0] = bucket.CeilUSD
  536. params[i][1] = bucket.Withdrawals
  537. params[i][2] = bucket.BlockWithdrawalRate
  538. params[i][3] = bucket.MaxWithdrawals
  539. }
  540. if tx, err = c.client.CallAuth(
  541. 12500000, //nolint:gomnd
  542. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  543. return c.hermez.UpdateBucketsParameters(auth, params)
  544. },
  545. ); err != nil {
  546. return nil, tracerr.Wrap(fmt.Errorf("Failed update Buckets Parameters: %w", err))
  547. }
  548. return tx, nil
  549. }
  550. // RollupUpdateTokenExchange is the interface to call the smart contract function
  551. func (c *RollupClient) RollupUpdateTokenExchange(addressArray []ethCommon.Address, valueArray []uint64) (tx *types.Transaction, err error) {
  552. if tx, err = c.client.CallAuth(
  553. 0,
  554. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  555. return c.hermez.UpdateTokenExchange(auth, addressArray, valueArray)
  556. },
  557. ); err != nil {
  558. return nil, tracerr.Wrap(fmt.Errorf("Failed update Token Exchange: %w", err))
  559. }
  560. return tx, nil
  561. }
  562. // RollupUpdateWithdrawalDelay is the interface to call the smart contract function
  563. func (c *RollupClient) RollupUpdateWithdrawalDelay(newWithdrawalDelay int64) (tx *types.Transaction, err error) {
  564. if tx, err = c.client.CallAuth(
  565. 0,
  566. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  567. return c.hermez.UpdateWithdrawalDelay(auth, uint64(newWithdrawalDelay))
  568. },
  569. ); err != nil {
  570. return nil, tracerr.Wrap(fmt.Errorf("Failed update WithdrawalDelay: %w", err))
  571. }
  572. return tx, nil
  573. }
  574. // RollupSafeMode is the interface to call the smart contract function
  575. func (c *RollupClient) RollupSafeMode() (tx *types.Transaction, err error) {
  576. if tx, err = c.client.CallAuth(
  577. 0,
  578. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  579. return c.hermez.SafeMode(auth)
  580. },
  581. ); err != nil {
  582. return nil, tracerr.Wrap(fmt.Errorf("Failed update Safe Mode: %w", err))
  583. }
  584. return tx, nil
  585. }
  586. // RollupInstantWithdrawalViewer is the interface to call the smart contract function
  587. func (c *RollupClient) RollupInstantWithdrawalViewer(tokenAddress ethCommon.Address, amount *big.Int) (instantAllowed bool, err error) {
  588. if err := c.client.Call(func(ec *ethclient.Client) error {
  589. instantAllowed, err = c.hermez.InstantWithdrawalViewer(c.opts, tokenAddress, amount)
  590. return tracerr.Wrap(err)
  591. }); err != nil {
  592. return false, tracerr.Wrap(err)
  593. }
  594. return instantAllowed, nil
  595. }
  596. // RollupConstants returns the Constants of the Rollup Smart Contract
  597. func (c *RollupClient) RollupConstants() (rollupConstants *common.RollupConstants, err error) {
  598. rollupConstants = new(common.RollupConstants)
  599. if err := c.client.Call(func(ec *ethclient.Client) error {
  600. absoluteMaxL1L2BatchTimeout, err := c.hermez.ABSOLUTEMAXL1L2BATCHTIMEOUT(c.opts)
  601. if err != nil {
  602. return tracerr.Wrap(err)
  603. }
  604. rollupConstants.AbsoluteMaxL1L2BatchTimeout = int64(absoluteMaxL1L2BatchTimeout)
  605. rollupConstants.TokenHEZ, err = c.hermez.TokenHEZ(c.opts)
  606. if err != nil {
  607. return tracerr.Wrap(err)
  608. }
  609. rollupVerifiersLength, err := c.hermez.RollupVerifiersLength(c.opts)
  610. if err != nil {
  611. return tracerr.Wrap(err)
  612. }
  613. for i := int64(0); i < rollupVerifiersLength.Int64(); i++ {
  614. var newRollupVerifier common.RollupVerifierStruct
  615. rollupVerifier, err := c.hermez.RollupVerifiers(c.opts, big.NewInt(i))
  616. if err != nil {
  617. return tracerr.Wrap(err)
  618. }
  619. newRollupVerifier.MaxTx = rollupVerifier.MaxTx.Int64()
  620. newRollupVerifier.NLevels = rollupVerifier.NLevels.Int64()
  621. rollupConstants.Verifiers = append(rollupConstants.Verifiers, newRollupVerifier)
  622. }
  623. rollupConstants.HermezAuctionContract, err = c.hermez.HermezAuctionContract(c.opts)
  624. if err != nil {
  625. return tracerr.Wrap(err)
  626. }
  627. rollupConstants.HermezGovernanceAddress, err = c.hermez.HermezGovernanceAddress(c.opts)
  628. if err != nil {
  629. return tracerr.Wrap(err)
  630. }
  631. rollupConstants.WithdrawDelayerContract, err = c.hermez.WithdrawDelayerContract(c.opts)
  632. return tracerr.Wrap(err)
  633. }); err != nil {
  634. return nil, tracerr.Wrap(err)
  635. }
  636. return rollupConstants, nil
  637. }
  638. var (
  639. logHermezL1UserTxEvent = crypto.Keccak256Hash([]byte("L1UserTxEvent(uint32,uint8,bytes)"))
  640. logHermezAddToken = crypto.Keccak256Hash([]byte("AddToken(address,uint32)"))
  641. logHermezForgeBatch = crypto.Keccak256Hash([]byte("ForgeBatch(uint32,uint16)"))
  642. logHermezUpdateForgeL1L2BatchTimeout = crypto.Keccak256Hash([]byte("UpdateForgeL1L2BatchTimeout(uint8)"))
  643. logHermezUpdateFeeAddToken = crypto.Keccak256Hash([]byte("UpdateFeeAddToken(uint256)"))
  644. logHermezWithdrawEvent = crypto.Keccak256Hash([]byte("WithdrawEvent(uint48,uint32,bool)"))
  645. logHermezUpdateBucketWithdraw = crypto.Keccak256Hash([]byte("UpdateBucketWithdraw(uint8,uint256,uint256)"))
  646. logHermezUpdateWithdrawalDelay = crypto.Keccak256Hash([]byte("UpdateWithdrawalDelay(uint64)"))
  647. logHermezUpdateBucketsParameters = crypto.Keccak256Hash([]byte("UpdateBucketsParameters(uint256[4][" +
  648. strconv.Itoa(common.RollupConstNumBuckets) + "])"))
  649. logHermezUpdateTokenExchange = crypto.Keccak256Hash([]byte("UpdateTokenExchange(address[],uint64[])"))
  650. logHermezSafeMode = crypto.Keccak256Hash([]byte("SafeMode()"))
  651. logHermezInitialize = crypto.Keccak256Hash([]byte("InitializeHermezEvent(uint8,uint256,uint64)"))
  652. )
  653. // RollupEventInit returns the initialize event with its corresponding block number
  654. func (c *RollupClient) RollupEventInit() (*RollupEventInitialize, int64, error) {
  655. query := ethereum.FilterQuery{
  656. Addresses: []ethCommon.Address{
  657. c.address,
  658. },
  659. Topics: [][]ethCommon.Hash{{logHermezInitialize}},
  660. }
  661. logs, err := c.client.client.FilterLogs(context.Background(), query)
  662. if err != nil {
  663. return nil, 0, tracerr.Wrap(err)
  664. }
  665. if len(logs) != 1 {
  666. return nil, 0, tracerr.Wrap(fmt.Errorf("no event of type InitializeHermezEvent found"))
  667. }
  668. vLog := logs[0]
  669. if vLog.Topics[0] != logHermezInitialize {
  670. return nil, 0, tracerr.Wrap(fmt.Errorf("event is not InitializeHermezEvent"))
  671. }
  672. var rollupInit RollupEventInitialize
  673. if err := c.contractAbi.UnpackIntoInterface(&rollupInit, "InitializeHermezEvent", vLog.Data); err != nil {
  674. return nil, 0, tracerr.Wrap(err)
  675. }
  676. return &rollupInit, int64(vLog.BlockNumber), tracerr.Wrap(err)
  677. }
  678. // RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
  679. func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error) {
  680. var rollupEvents RollupEvents
  681. var blockHash *ethCommon.Hash
  682. query := ethereum.FilterQuery{
  683. FromBlock: big.NewInt(blockNum),
  684. ToBlock: big.NewInt(blockNum),
  685. Addresses: []ethCommon.Address{
  686. c.address,
  687. },
  688. BlockHash: nil,
  689. Topics: [][]ethCommon.Hash{},
  690. }
  691. logs, err := c.client.client.FilterLogs(context.Background(), query)
  692. if err != nil {
  693. return nil, nil, tracerr.Wrap(err)
  694. }
  695. if len(logs) > 0 {
  696. blockHash = &logs[0].BlockHash
  697. }
  698. for _, vLog := range logs {
  699. if vLog.BlockHash != *blockHash {
  700. log.Errorw("Block hash mismatch", "expected", blockHash.String(), "got", vLog.BlockHash.String())
  701. return nil, nil, tracerr.Wrap(ErrBlockHashMismatchEvent)
  702. }
  703. switch vLog.Topics[0] {
  704. case logHermezL1UserTxEvent:
  705. var L1UserTxAux rollupEventL1UserTxAux
  706. var L1UserTx RollupEventL1UserTx
  707. err := c.contractAbi.UnpackIntoInterface(&L1UserTxAux, "L1UserTxEvent", vLog.Data)
  708. if err != nil {
  709. return nil, nil, tracerr.Wrap(err)
  710. }
  711. L1Tx, err := common.L1UserTxFromBytes(L1UserTxAux.L1UserTx)
  712. if err != nil {
  713. return nil, nil, tracerr.Wrap(err)
  714. }
  715. toForgeL1TxsNum := new(big.Int).SetBytes(vLog.Topics[1][:]).Int64()
  716. L1Tx.ToForgeL1TxsNum = &toForgeL1TxsNum
  717. L1Tx.Position = int(new(big.Int).SetBytes(vLog.Topics[2][:]).Int64())
  718. L1Tx.UserOrigin = true
  719. L1UserTx.L1UserTx = *L1Tx
  720. rollupEvents.L1UserTx = append(rollupEvents.L1UserTx, L1UserTx)
  721. case logHermezAddToken:
  722. var addToken RollupEventAddToken
  723. err := c.contractAbi.UnpackIntoInterface(&addToken, "AddToken", vLog.Data)
  724. if err != nil {
  725. return nil, nil, tracerr.Wrap(err)
  726. }
  727. addToken.TokenAddress = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
  728. rollupEvents.AddToken = append(rollupEvents.AddToken, addToken)
  729. case logHermezForgeBatch:
  730. var forgeBatch RollupEventForgeBatch
  731. err := c.contractAbi.UnpackIntoInterface(&forgeBatch, "ForgeBatch", vLog.Data)
  732. if err != nil {
  733. return nil, nil, tracerr.Wrap(err)
  734. }
  735. forgeBatch.BatchNum = new(big.Int).SetBytes(vLog.Topics[1][:]).Int64()
  736. forgeBatch.EthTxHash = vLog.TxHash
  737. // forgeBatch.Sender = vLog.Address
  738. rollupEvents.ForgeBatch = append(rollupEvents.ForgeBatch, forgeBatch)
  739. case logHermezUpdateForgeL1L2BatchTimeout:
  740. var updateForgeL1L2BatchTimeout struct {
  741. NewForgeL1L2BatchTimeout uint8
  742. }
  743. err := c.contractAbi.UnpackIntoInterface(&updateForgeL1L2BatchTimeout, "UpdateForgeL1L2BatchTimeout", vLog.Data)
  744. if err != nil {
  745. return nil, nil, tracerr.Wrap(err)
  746. }
  747. rollupEvents.UpdateForgeL1L2BatchTimeout = append(rollupEvents.UpdateForgeL1L2BatchTimeout,
  748. RollupEventUpdateForgeL1L2BatchTimeout{
  749. NewForgeL1L2BatchTimeout: int64(updateForgeL1L2BatchTimeout.NewForgeL1L2BatchTimeout),
  750. })
  751. case logHermezUpdateFeeAddToken:
  752. var updateFeeAddToken RollupEventUpdateFeeAddToken
  753. err := c.contractAbi.UnpackIntoInterface(&updateFeeAddToken, "UpdateFeeAddToken", vLog.Data)
  754. if err != nil {
  755. return nil, nil, tracerr.Wrap(err)
  756. }
  757. rollupEvents.UpdateFeeAddToken = append(rollupEvents.UpdateFeeAddToken, updateFeeAddToken)
  758. case logHermezWithdrawEvent:
  759. var withdraw RollupEventWithdraw
  760. withdraw.Idx = new(big.Int).SetBytes(vLog.Topics[1][:]).Uint64()
  761. withdraw.NumExitRoot = new(big.Int).SetBytes(vLog.Topics[2][:]).Uint64()
  762. instantWithdraw := new(big.Int).SetBytes(vLog.Topics[3][:]).Uint64()
  763. if instantWithdraw == 1 {
  764. withdraw.InstantWithdraw = true
  765. }
  766. withdraw.TxHash = vLog.TxHash
  767. rollupEvents.Withdraw = append(rollupEvents.Withdraw, withdraw)
  768. case logHermezUpdateBucketWithdraw:
  769. var updateBucketWithdrawAux rollupEventUpdateBucketWithdrawAux
  770. var updateBucketWithdraw RollupEventUpdateBucketWithdraw
  771. err := c.contractAbi.UnpackIntoInterface(&updateBucketWithdrawAux, "UpdateBucketWithdraw", vLog.Data)
  772. if err != nil {
  773. return nil, nil, tracerr.Wrap(err)
  774. }
  775. updateBucketWithdraw.Withdrawals = updateBucketWithdrawAux.Withdrawals
  776. updateBucketWithdraw.NumBucket = int(new(big.Int).SetBytes(vLog.Topics[1][:]).Int64())
  777. updateBucketWithdraw.BlockStamp = new(big.Int).SetBytes(vLog.Topics[2][:]).Int64()
  778. rollupEvents.UpdateBucketWithdraw = append(rollupEvents.UpdateBucketWithdraw, updateBucketWithdraw)
  779. case logHermezUpdateWithdrawalDelay:
  780. var withdrawalDelay RollupEventUpdateWithdrawalDelay
  781. err := c.contractAbi.UnpackIntoInterface(&withdrawalDelay, "UpdateWithdrawalDelay", vLog.Data)
  782. if err != nil {
  783. return nil, nil, tracerr.Wrap(err)
  784. }
  785. rollupEvents.UpdateWithdrawalDelay = append(rollupEvents.UpdateWithdrawalDelay, withdrawalDelay)
  786. case logHermezUpdateBucketsParameters:
  787. var bucketsParametersAux rollupEventUpdateBucketsParametersAux
  788. var bucketsParameters RollupEventUpdateBucketsParameters
  789. err := c.contractAbi.UnpackIntoInterface(&bucketsParametersAux, "UpdateBucketsParameters", vLog.Data)
  790. if err != nil {
  791. return nil, nil, tracerr.Wrap(err)
  792. }
  793. for i, bucket := range bucketsParametersAux.ArrayBuckets {
  794. bucketsParameters.ArrayBuckets[i].CeilUSD = bucket[0]
  795. bucketsParameters.ArrayBuckets[i].Withdrawals = bucket[1]
  796. bucketsParameters.ArrayBuckets[i].BlockWithdrawalRate = bucket[2]
  797. bucketsParameters.ArrayBuckets[i].MaxWithdrawals = bucket[3]
  798. }
  799. rollupEvents.UpdateBucketsParameters = append(rollupEvents.UpdateBucketsParameters, bucketsParameters)
  800. case logHermezUpdateTokenExchange:
  801. var tokensExchange RollupEventUpdateTokenExchange
  802. err := c.contractAbi.UnpackIntoInterface(&tokensExchange, "UpdateTokenExchange", vLog.Data)
  803. if err != nil {
  804. return nil, nil, tracerr.Wrap(err)
  805. }
  806. rollupEvents.UpdateTokenExchange = append(rollupEvents.UpdateTokenExchange, tokensExchange)
  807. case logHermezSafeMode:
  808. var safeMode RollupEventSafeMode
  809. rollupEvents.SafeMode = append(rollupEvents.SafeMode, safeMode)
  810. // Also add an UpdateBucketsParameter with
  811. // SafeMode=true to keep the order between `safeMode`
  812. // and `UpdateBucketsParameters`
  813. bucketsParameters := RollupEventUpdateBucketsParameters{
  814. SafeMode: true,
  815. }
  816. for i := range bucketsParameters.ArrayBuckets {
  817. bucketsParameters.ArrayBuckets[i].CeilUSD = big.NewInt(0)
  818. bucketsParameters.ArrayBuckets[i].Withdrawals = big.NewInt(0)
  819. bucketsParameters.ArrayBuckets[i].BlockWithdrawalRate = big.NewInt(0)
  820. bucketsParameters.ArrayBuckets[i].MaxWithdrawals = big.NewInt(0)
  821. }
  822. rollupEvents.UpdateBucketsParameters = append(rollupEvents.UpdateBucketsParameters,
  823. bucketsParameters)
  824. }
  825. }
  826. return &rollupEvents, blockHash, nil
  827. }
  828. // RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the
  829. // Rollup Smart Contract in the given transaction, and the sender address.
  830. func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash, l1UserTxsLen uint16) (*RollupForgeBatchArgs, *ethCommon.Address, error) {
  831. tx, _, err := c.client.client.TransactionByHash(context.Background(), ethTxHash)
  832. if err != nil {
  833. return nil, nil, tracerr.Wrap(err)
  834. }
  835. txData := tx.Data()
  836. method, err := c.contractAbi.MethodById(txData[:4])
  837. if err != nil {
  838. return nil, nil, tracerr.Wrap(err)
  839. }
  840. receipt, err := c.client.client.TransactionReceipt(context.Background(), ethTxHash)
  841. if err != nil {
  842. return nil, nil, tracerr.Wrap(err)
  843. }
  844. sender, err := c.client.client.TransactionSender(context.Background(), tx, receipt.Logs[0].BlockHash, receipt.Logs[0].Index)
  845. if err != nil {
  846. return nil, nil, tracerr.Wrap(err)
  847. }
  848. var aux rollupForgeBatchArgsAux
  849. if values, err := method.Inputs.Unpack(txData[4:]); err != nil {
  850. return nil, nil, tracerr.Wrap(err)
  851. } else if err := method.Inputs.Copy(&aux, values); err != nil {
  852. return nil, nil, tracerr.Wrap(err)
  853. }
  854. rollupForgeBatchArgs := RollupForgeBatchArgs{
  855. L1Batch: aux.L1Batch,
  856. NewExitRoot: aux.NewExitRoot,
  857. NewLastIdx: aux.NewLastIdx.Int64(),
  858. NewStRoot: aux.NewStRoot,
  859. ProofA: aux.ProofA,
  860. ProofB: aux.ProofB,
  861. ProofC: aux.ProofC,
  862. VerifierIdx: aux.VerifierIdx,
  863. L1CoordinatorTxs: []common.L1Tx{},
  864. L1CoordinatorTxsAuths: [][]byte{},
  865. L2TxsData: []common.L2Tx{},
  866. FeeIdxCoordinator: []common.Idx{},
  867. }
  868. nLevels := c.consts.Verifiers[rollupForgeBatchArgs.VerifierIdx].NLevels
  869. lenL1L2TxsBytes := int((nLevels/8)*2 + 2 + 1)
  870. numBytesL1TxUser := int(l1UserTxsLen) * lenL1L2TxsBytes
  871. numTxsL1Coord := len(aux.EncodedL1CoordinatorTx) / common.L1CoordinatorTxBytesLen
  872. numBytesL1TxCoord := numTxsL1Coord * lenL1L2TxsBytes
  873. numBeginL2Tx := numBytesL1TxCoord + numBytesL1TxUser
  874. l1UserTxsData := []byte{}
  875. if l1UserTxsLen > 0 {
  876. l1UserTxsData = aux.L1L2TxsData[:numBytesL1TxUser]
  877. }
  878. for i := 0; i < int(l1UserTxsLen); i++ {
  879. l1Tx, err := common.L1TxFromDataAvailability(l1UserTxsData[i*lenL1L2TxsBytes:(i+1)*lenL1L2TxsBytes], uint32(nLevels))
  880. if err != nil {
  881. return nil, nil, tracerr.Wrap(err)
  882. }
  883. rollupForgeBatchArgs.L1UserTxs = append(rollupForgeBatchArgs.L1UserTxs, *l1Tx)
  884. }
  885. l2TxsData := []byte{}
  886. if numBeginL2Tx < len(aux.L1L2TxsData) {
  887. l2TxsData = aux.L1L2TxsData[numBeginL2Tx:]
  888. }
  889. numTxsL2 := len(l2TxsData) / lenL1L2TxsBytes
  890. for i := 0; i < numTxsL2; i++ {
  891. l2Tx, err := common.L2TxFromBytesDataAvailability(l2TxsData[i*lenL1L2TxsBytes:(i+1)*lenL1L2TxsBytes], int(nLevels))
  892. if err != nil {
  893. return nil, nil, tracerr.Wrap(err)
  894. }
  895. rollupForgeBatchArgs.L2TxsData = append(rollupForgeBatchArgs.L2TxsData, *l2Tx)
  896. }
  897. for i := 0; i < numTxsL1Coord; i++ {
  898. bytesL1Coordinator := aux.EncodedL1CoordinatorTx[i*common.L1CoordinatorTxBytesLen : (i+1)*common.L1CoordinatorTxBytesLen]
  899. var signature []byte
  900. v := bytesL1Coordinator[0]
  901. s := bytesL1Coordinator[1:33]
  902. r := bytesL1Coordinator[33:65]
  903. signature = append(signature, r[:]...)
  904. signature = append(signature, s[:]...)
  905. signature = append(signature, v)
  906. l1Tx, err := common.L1CoordinatorTxFromBytes(bytesL1Coordinator, c.chainID, c.address)
  907. if err != nil {
  908. return nil, nil, tracerr.Wrap(err)
  909. }
  910. rollupForgeBatchArgs.L1CoordinatorTxs = append(rollupForgeBatchArgs.L1CoordinatorTxs, *l1Tx)
  911. rollupForgeBatchArgs.L1CoordinatorTxsAuths = append(rollupForgeBatchArgs.L1CoordinatorTxsAuths, signature)
  912. }
  913. lenFeeIdxCoordinatorBytes := int(nLevels / 8) //nolint:gomnd
  914. numFeeIdxCoordinator := len(aux.FeeIdxCoordinator) / lenFeeIdxCoordinatorBytes
  915. for i := 0; i < numFeeIdxCoordinator; i++ {
  916. var paddedFeeIdx [6]byte
  917. // TODO: This check is not necessary: the first case will always work. Test it before removing the if.
  918. if lenFeeIdxCoordinatorBytes < common.IdxBytesLen {
  919. copy(paddedFeeIdx[6-lenFeeIdxCoordinatorBytes:], aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
  920. } else {
  921. copy(paddedFeeIdx[:], aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
  922. }
  923. feeIdxCoordinator, err := common.IdxFromBytes(paddedFeeIdx[:])
  924. if err != nil {
  925. return nil, nil, tracerr.Wrap(err)
  926. }
  927. if feeIdxCoordinator != common.Idx(0) {
  928. rollupForgeBatchArgs.FeeIdxCoordinator = append(rollupForgeBatchArgs.FeeIdxCoordinator, feeIdxCoordinator)
  929. }
  930. }
  931. return &rollupForgeBatchArgs, &sender, nil
  932. }