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