hermez-node/eth/auction.go
eth/auction.goRaw
1package eth
2
3import (
4 "encoding/binary"
5 "fmt"
6 "math/big"
7
8 "github.com/ethereum/go-ethereum/accounts/abi/bind"
9 ethCommon "github.com/ethereum/go-ethereum/common"
10 "github.com/ethereum/go-ethereum/core/types"
11 "github.com/ethereum/go-ethereum/ethclient"
12 HermezAuctionProtocol "github.com/hermeznetwork/hermez-node/eth/contracts/auction"
13 ERC777 "github.com/hermeznetwork/hermez-node/eth/contracts/erc777"
14 "github.com/hermeznetwork/hermez-node/log"
15 "golang.org/x/crypto/sha3"
16)
17
18// AuctionConstants are the constants of the Rollup Smart Contract
19type AuctionConstants struct {
20 // Blocks per slot
21 BlocksPerSlot uint8
22 // Minimum bid when no one has bid yet
23 InitialMinimalBidding *big.Int
24 // First block where the first slot begins
25 GenesisBlockNum int64
26 // Hermez Governanze Token smartcontract address who controls some parameters and collects HEZ fee
27 // Only for test
28 GovernanceAddress ethCommon.Address
29 // ERC777 token with which the bids will be made
30 TokenHEZ ethCommon.Address
31 // HermezRollup smartcontract address
32 HermezRollup ethCommon.Address
33}
34
35// SlotState is the state of a slot
36type SlotState struct {
37 Forger ethCommon.Address
38 BidAmount *big.Int
39 ClosedMinBid *big.Int
40 Fulfilled bool
41}
42
43// NewSlotState returns an empty SlotState
44func NewSlotState() *SlotState {
45 return &SlotState{
46 Forger: ethCommon.Address{},
47 BidAmount: big.NewInt(0),
48 ClosedMinBid: big.NewInt(0),
49 Fulfilled: false,
50 }
51}
52
53// Coordinator is the details of the Coordinator identified by the forger address
54type Coordinator struct {
55 WithdrawalAddress ethCommon.Address
56 URL string
57}
58
59// AuctionVariables are the variables of the Auction Smart Contract
60type AuctionVariables struct {
61 // Boot Coordinator Address
62 DonationAddress ethCommon.Address
63 // Boot Coordinator Address
64 BootCoordinator ethCommon.Address
65 // The minimum bid value in a series of 6 slots
66 DefaultSlotSetBid [6]*big.Int
67 // Distance (#slots) to the closest slot to which you can bid ( 2 Slots = 2 * 40 Blocks = 20 min )
68 ClosedAuctionSlots uint16
69 // Distance (#slots) to the farthest slot to which you can bid (30 days = 4320 slots )
70 OpenAuctionSlots uint16
71 // How the HEZ tokens deposited by the slot winner are distributed (Burn: 40% - Donation: 40% - HGT: 20%)
72 AllocationRatio [3]uint16
73 // Minimum outbid (percentage) over the previous one to consider it valid
74 Outbidding uint16
75 // Number of blocks at the end of a slot in which any coordinator can forge if the winner has not forged one before
76 SlotDeadline uint8
77}
78
79// AuctionState represents the state of the Rollup in the Smart Contract
80type AuctionState struct {
81 // Mapping to control slot state
82 Slots map[int64]*SlotState
83 // Mapping to control balances pending to claim
84 PendingBalances map[ethCommon.Address]*big.Int
85 // Mapping to register all the coordinators. The address used for the mapping is the forger address
86 Coordinators map[ethCommon.Address]*Coordinator
87}
88
89// AuctionEventNewBid is an event of the Auction Smart Contract
90type AuctionEventNewBid struct {
91 Slot int64
92 BidAmount *big.Int
93 CoordinatorForger ethCommon.Address
94}
95
96// AuctionEventNewSlotDeadline is an event of the Auction Smart Contract
97type AuctionEventNewSlotDeadline struct {
98 NewSlotDeadline uint8
99}
100
101// AuctionEventNewClosedAuctionSlots is an event of the Auction Smart Contract
102type AuctionEventNewClosedAuctionSlots struct {
103 NewClosedAuctionSlots uint16
104}
105
106// AuctionEventNewOutbidding is an event of the Auction Smart Contract
107type AuctionEventNewOutbidding struct {
108 NewOutbidding uint16
109}
110
111// AuctionEventNewDonationAddress is an event of the Auction Smart Contract
112type AuctionEventNewDonationAddress struct {
113 NewDonationAddress ethCommon.Address
114}
115
116// AuctionEventNewBootCoordinator is an event of the Auction Smart Contract
117type AuctionEventNewBootCoordinator struct {
118 NewBootCoordinator ethCommon.Address
119}
120
121// AuctionEventNewOpenAuctionSlots is an event of the Auction Smart Contract
122type AuctionEventNewOpenAuctionSlots struct {
123 NewOpenAuctionSlots uint16
124}
125
126// AuctionEventNewAllocationRatio is an event of the Auction Smart Contract
127type AuctionEventNewAllocationRatio struct {
128 NewAllocationRatio [3]uint16
129}
130
131// AuctionEventNewCoordinator is an event of the Auction Smart Contract
132type AuctionEventNewCoordinator struct {
133 ForgerAddress ethCommon.Address
134 WithdrawalAddress ethCommon.Address
135 URL string
136}
137
138// AuctionEventCoordinatorUpdated is an event of the Auction Smart Contract
139type AuctionEventCoordinatorUpdated struct {
140 ForgerAddress ethCommon.Address
141 WithdrawalAddress ethCommon.Address
142 URL string
143}
144
145// AuctionEventNewForgeAllocated is an event of the Auction Smart Contract
146type AuctionEventNewForgeAllocated struct {
147 Forger ethCommon.Address
148 CurrentSlot int64
149 BurnAmount *big.Int
150 DonationAmount *big.Int
151 GovernanceAmount *big.Int
152}
153
154// AuctionEventNewDefaultSlotSetBid is an event of the Auction Smart Contract
155type AuctionEventNewDefaultSlotSetBid struct {
156 SlotSet int64
157 NewInitialMinBid *big.Int
158}
159
160// AuctionEventNewForge is an event of the Auction Smart Contract
161type AuctionEventNewForge struct {
162 Forger ethCommon.Address
163 CurrentSlot int64
164}
165
166// AuctionEventHEZClaimed is an event of the Auction Smart Contract
167type AuctionEventHEZClaimed struct {
168 Owner ethCommon.Address
169 Amount *big.Int
170}
171
172// AuctionEvents is the list of events in a block of the Auction Smart Contract
173type AuctionEvents struct { //nolint:structcheck
174 NewBid []AuctionEventNewBid
175 NewSlotDeadline []AuctionEventNewSlotDeadline
176 NewClosedAuctionSlots []AuctionEventNewClosedAuctionSlots
177 NewOutbidding []AuctionEventNewOutbidding
178 NewDonationAddress []AuctionEventNewDonationAddress
179 NewBootCoordinator []AuctionEventNewBootCoordinator
180 NewOpenAuctionSlots []AuctionEventNewOpenAuctionSlots
181 NewAllocationRatio []AuctionEventNewAllocationRatio
182 NewCoordinator []AuctionEventNewCoordinator
183 CoordinatorUpdated []AuctionEventCoordinatorUpdated
184 NewForgeAllocated []AuctionEventNewForgeAllocated
185 NewDefaultSlotSetBid []AuctionEventNewDefaultSlotSetBid
186 NewForge []AuctionEventNewForge
187 HEZClaimed []AuctionEventHEZClaimed
188}
189
190// NewAuctionEvents creates an empty AuctionEvents with the slices initialized.
191func NewAuctionEvents() AuctionEvents {
192 return AuctionEvents{
193 NewBid: make([]AuctionEventNewBid, 0),
194 NewSlotDeadline: make([]AuctionEventNewSlotDeadline, 0),
195 NewClosedAuctionSlots: make([]AuctionEventNewClosedAuctionSlots, 0),
196 NewOutbidding: make([]AuctionEventNewOutbidding, 0),
197 NewDonationAddress: make([]AuctionEventNewDonationAddress, 0),
198 NewBootCoordinator: make([]AuctionEventNewBootCoordinator, 0),
199 NewOpenAuctionSlots: make([]AuctionEventNewOpenAuctionSlots, 0),
200 NewAllocationRatio: make([]AuctionEventNewAllocationRatio, 0),
201 NewCoordinator: make([]AuctionEventNewCoordinator, 0),
202 CoordinatorUpdated: make([]AuctionEventCoordinatorUpdated, 0),
203 NewForgeAllocated: make([]AuctionEventNewForgeAllocated, 0),
204 NewDefaultSlotSetBid: make([]AuctionEventNewDefaultSlotSetBid, 0),
205 NewForge: make([]AuctionEventNewForge, 0),
206 HEZClaimed: make([]AuctionEventHEZClaimed, 0),
207 }
208}
209
210// AuctionInterface is the inteface to to Auction Smart Contract
211type AuctionInterface interface {
212 //
213 // Smart Contract Methods
214 //
215
216 // Getter/Setter, where Setter is onlyOwner
217 AuctionSetSlotDeadline(newDeadline uint8) (*types.Transaction, error)
218 AuctionGetSlotDeadline() (uint8, error)
219 AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (*types.Transaction, error)
220 AuctionGetOpenAuctionSlots() (uint16, error)
221 AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (*types.Transaction, error)
222 AuctionGetClosedAuctionSlots() (uint16, error)
223 AuctionSetOutbidding(newOutbidding uint16) (*types.Transaction, error)
224 AuctionGetOutbidding() (uint16, error)
225 AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (*types.Transaction, error)
226 AuctionGetAllocationRatio() ([3]uint16, error)
227 AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (*types.Transaction, error)
228 AuctionGetDonationAddress() (*ethCommon.Address, error)
229 AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (*types.Transaction, error)
230 AuctionGetBootCoordinator() (*ethCommon.Address, error)
231 AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (*types.Transaction, error)
232
233 // Coordinator Management
234 AuctionRegisterCoordinator(forgerAddress ethCommon.Address, URL string) (*types.Transaction, error)
235 AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error)
236 AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (*types.Transaction, error)
237
238 // Slot Info
239 AuctionGetCurrentSlotNumber() (int64, error)
240 AuctionGetMinBidBySlot(slot int64) (*big.Int, error)
241 AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error)
242
243 // Bidding
244 // AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int,
245 // userData, operatorData []byte) error // Only called from another smart contract
246 AuctionBid(slot int64, bidAmount *big.Int, forger, tokenAddress ethCommon.Address) (*types.Transaction, error)
247 AuctionMultiBid(startingSlot int64, endingSlot int64, slotSet [6]bool, maxBid, closedMinBid, budget *big.Int, forger, tokenAddress ethCommon.Address) (*types.Transaction, error)
248
249 // Forge
250 AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error)
251 // AuctionForge(forger ethCommon.Address) (bool, error) // Only called from another smart contract
252
253 // Fees
254 AuctionClaimHEZ(claimAddress ethCommon.Address) (*types.Transaction, error)
255
256 //
257 // Smart Contract Status
258 //
259
260 AuctionConstants() (*AuctionConstants, error)
261 AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *ethCommon.Hash, error)
262}
263
264//
265// Implementation
266//
267
268// AuctionClient is the implementation of the interface to the Auction Smart Contract in ethereum.
269type AuctionClient struct {
270 client *EthereumClient
271 address ethCommon.Address
272 gasLimit uint64
273}
274
275// NewAuctionClient creates a new AuctionClient
276func NewAuctionClient(client *EthereumClient, address ethCommon.Address) *AuctionClient {
277 return &AuctionClient{
278 client: client,
279 address: address,
280 gasLimit: 1000000, //nolint:gomnd
281 }
282}
283
284// AuctionSetSlotDeadline is the interface to call the smart contract function
285func (c *AuctionClient) AuctionSetSlotDeadline(newDeadline uint8) (*types.Transaction, error) {
286 var tx *types.Transaction
287 var err error
288 if tx, err = c.client.CallAuth(
289 c.gasLimit,
290 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
291 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
292 if err != nil {
293 return nil, err
294 }
295 return auction.SetSlotDeadline(auth, newDeadline)
296 },
297 ); err != nil {
298 return nil, fmt.Errorf("Failed setting slotDeadline: %w", err)
299 }
300 return tx, nil
301}
302
303// AuctionGetSlotDeadline is the interface to call the smart contract function
304func (c *AuctionClient) AuctionGetSlotDeadline() (uint8, error) {
305 var slotDeadline uint8
306 if err := c.client.Call(func(ec *ethclient.Client) error {
307 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
308 if err != nil {
309 return err
310 }
311 slotDeadline, err = auction.GetSlotDeadline(nil)
312 return err
313 }); err != nil {
314 return 0, err
315 }
316 return slotDeadline, nil
317}
318
319// AuctionSetOpenAuctionSlots is the interface to call the smart contract function
320func (c *AuctionClient) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (*types.Transaction, error) {
321 var tx *types.Transaction
322 var err error
323 if tx, err = c.client.CallAuth(
324 c.gasLimit,
325 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
326 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
327 if err != nil {
328 return nil, err
329 }
330 return auction.SetOpenAuctionSlots(auth, newOpenAuctionSlots)
331 },
332 ); err != nil {
333 return nil, fmt.Errorf("Failed setting openAuctionSlots: %w", err)
334 }
335 return tx, nil
336}
337
338// AuctionGetOpenAuctionSlots is the interface to call the smart contract function
339func (c *AuctionClient) AuctionGetOpenAuctionSlots() (uint16, error) {
340 var openAuctionSlots uint16
341 if err := c.client.Call(func(ec *ethclient.Client) error {
342 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
343 if err != nil {
344 return err
345 }
346 openAuctionSlots, err = auction.GetOpenAuctionSlots(nil)
347 return err
348 }); err != nil {
349 return 0, err
350 }
351 return openAuctionSlots, nil
352}
353
354// AuctionSetClosedAuctionSlots is the interface to call the smart contract function
355func (c *AuctionClient) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (*types.Transaction, error) {
356 var tx *types.Transaction
357 var err error
358 if tx, err = c.client.CallAuth(
359 c.gasLimit,
360 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
361 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
362 if err != nil {
363 return nil, err
364 }
365 return auction.SetClosedAuctionSlots(auth, newClosedAuctionSlots)
366 },
367 ); err != nil {
368 return nil, fmt.Errorf("Failed setting closedAuctionSlots: %w", err)
369 }
370 return tx, nil
371}
372
373// AuctionGetClosedAuctionSlots is the interface to call the smart contract function
374func (c *AuctionClient) AuctionGetClosedAuctionSlots() (uint16, error) {
375 var closedAuctionSlots uint16
376 if err := c.client.Call(func(ec *ethclient.Client) error {
377 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
378 if err != nil {
379 return err
380 }
381 closedAuctionSlots, err = auction.GetClosedAuctionSlots(nil)
382 return err
383 }); err != nil {
384 return 0, err
385 }
386 return closedAuctionSlots, nil
387}
388
389// AuctionSetOutbidding is the interface to call the smart contract function
390func (c *AuctionClient) AuctionSetOutbidding(newOutbidding uint16) (*types.Transaction, error) {
391 var tx *types.Transaction
392 var err error
393 if tx, err = c.client.CallAuth(
394 12500000, //nolint:gomnd
395 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
396 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
397 if err != nil {
398 return nil, err
399 }
400 return auction.SetOutbidding(auth, newOutbidding)
401 },
402 ); err != nil {
403 return nil, fmt.Errorf("Failed setting setOutbidding: %w", err)
404 }
405 return tx, nil
406}
407
408// AuctionGetOutbidding is the interface to call the smart contract function
409func (c *AuctionClient) AuctionGetOutbidding() (uint16, error) {
410 var outbidding uint16
411 if err := c.client.Call(func(ec *ethclient.Client) error {
412 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
413 if err != nil {
414 return err
415 }
416 outbidding, err = auction.GetOutbidding(nil)
417 return err
418 }); err != nil {
419 return 0, err
420 }
421 return outbidding, nil
422}
423
424// AuctionSetAllocationRatio is the interface to call the smart contract function
425func (c *AuctionClient) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (*types.Transaction, error) {
426 var tx *types.Transaction
427 var err error
428 if tx, err = c.client.CallAuth(
429 c.gasLimit,
430 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
431 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
432 if err != nil {
433 return nil, err
434 }
435 return auction.SetAllocationRatio(auth, newAllocationRatio)
436 },
437 ); err != nil {
438 return nil, fmt.Errorf("Failed setting allocationRatio: %w", err)
439 }
440 return tx, nil
441}
442
443// AuctionGetAllocationRatio is the interface to call the smart contract function
444func (c *AuctionClient) AuctionGetAllocationRatio() ([3]uint16, error) {
445 var allocationRation [3]uint16
446 if err := c.client.Call(func(ec *ethclient.Client) error {
447 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
448 if err != nil {
449 return err
450 }
451 allocationRation, err = auction.GetAllocationRatio(nil)
452 return err
453 }); err != nil {
454 return [3]uint16{}, err
455 }
456 return allocationRation, nil
457}
458
459// AuctionSetDonationAddress is the interface to call the smart contract function
460func (c *AuctionClient) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (*types.Transaction, error) {
461 var tx *types.Transaction
462 var err error
463 if tx, err = c.client.CallAuth(
464 c.gasLimit,
465 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
466 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
467 if err != nil {
468 return nil, err
469 }
470 return auction.SetDonationAddress(auth, newDonationAddress)
471 },
472 ); err != nil {
473 return nil, fmt.Errorf("Failed setting donationAddress: %w", err)
474 }
475 return tx, nil
476}
477
478// AuctionGetDonationAddress is the interface to call the smart contract function
479func (c *AuctionClient) AuctionGetDonationAddress() (*ethCommon.Address, error) {
480 var donationAddress ethCommon.Address
481 if err := c.client.Call(func(ec *ethclient.Client) error {
482 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
483 if err != nil {
484 return err
485 }
486 donationAddress, err = auction.GetDonationAddress(nil)
487 return err
488 }); err != nil {
489 return nil, err
490 }
491 return &donationAddress, nil
492}
493
494// AuctionSetBootCoordinator is the interface to call the smart contract function
495func (c *AuctionClient) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (*types.Transaction, error) {
496 var tx *types.Transaction
497 var err error
498 if tx, err = c.client.CallAuth(
499 c.gasLimit,
500 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
501 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
502 if err != nil {
503 return nil, err
504 }
505 return auction.SetBootCoordinator(auth, newBootCoordinator)
506 },
507 ); err != nil {
508 return nil, fmt.Errorf("Failed setting bootCoordinator: %w", err)
509 }
510 return tx, nil
511}
512
513// AuctionGetBootCoordinator is the interface to call the smart contract function
514func (c *AuctionClient) AuctionGetBootCoordinator() (*ethCommon.Address, error) {
515 var bootCoordinator ethCommon.Address
516 if err := c.client.Call(func(ec *ethclient.Client) error {
517 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
518 if err != nil {
519 return err
520 }
521 bootCoordinator, err = auction.GetBootCoordinator(nil)
522 return err
523 }); err != nil {
524 return nil, err
525 }
526 return &bootCoordinator, nil
527}
528
529// AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function
530func (c *AuctionClient) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (*types.Transaction, error) {
531 var tx *types.Transaction
532 var err error
533 if tx, err = c.client.CallAuth(
534 c.gasLimit,
535 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
536 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
537 if err != nil {
538 return nil, err
539 }
540 slotSetToSend := big.NewInt(slotSet)
541 return auction.ChangeDefaultSlotSetBid(auth, slotSetToSend, newInitialMinBid)
542 },
543 ); err != nil {
544 return nil, fmt.Errorf("Failed changing slotSet Bid: %w", err)
545 }
546 return tx, nil
547}
548
549// AuctionGetClaimableHEZ is the interface to call the smart contract function
550func (c *AuctionClient) AuctionGetClaimableHEZ(claimAddress ethCommon.Address) (*big.Int, error) {
551 var claimableHEZ *big.Int
552 if err := c.client.Call(func(ec *ethclient.Client) error {
553 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
554 if err != nil {
555 return err
556 }
557 claimableHEZ, err = auction.GetClaimableHEZ(nil, claimAddress)
558 return err
559 }); err != nil {
560 return nil, err
561 }
562 return claimableHEZ, nil
563}
564
565// AuctionRegisterCoordinator is the interface to call the smart contract function
566func (c *AuctionClient) AuctionRegisterCoordinator(forgerAddress ethCommon.Address, URL string) (*types.Transaction, error) {
567 var tx *types.Transaction
568 var err error
569 if tx, err = c.client.CallAuth(
570 c.gasLimit,
571 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
572 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
573 if err != nil {
574 return nil, err
575 }
576 return auction.RegisterCoordinator(auth, forgerAddress, URL)
577 },
578 ); err != nil {
579 return nil, fmt.Errorf("Failed register coordinator: %w", err)
580 }
581 return tx, nil
582}
583
584// AuctionIsRegisteredCoordinator is the interface to call the smart contract function
585func (c *AuctionClient) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) {
586 var registered bool
587 if err := c.client.Call(func(ec *ethclient.Client) error {
588 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
589 if err != nil {
590 return err
591 }
592 registered, err = auction.IsRegisteredCoordinator(nil, forgerAddress)
593 return err
594 }); err != nil {
595 return false, err
596 }
597 return registered, nil
598}
599
600// AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
601func (c *AuctionClient) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (*types.Transaction, error) {
602 var tx *types.Transaction
603 var err error
604 if tx, err = c.client.CallAuth(
605 c.gasLimit,
606 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
607 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
608 if err != nil {
609 return nil, err
610 }
611 return auction.UpdateCoordinatorInfo(auth, forgerAddress, newWithdrawAddress, newURL)
612 },
613 ); err != nil {
614 return nil, fmt.Errorf("Failed update coordinator info: %w", err)
615 }
616 return tx, nil
617}
618
619// AuctionGetCurrentSlotNumber is the interface to call the smart contract function
620func (c *AuctionClient) AuctionGetCurrentSlotNumber() (int64, error) {
621 var _currentSlotNumber *big.Int
622 if err := c.client.Call(func(ec *ethclient.Client) error {
623 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
624 if err != nil {
625 return err
626 }
627 _currentSlotNumber, err = auction.GetCurrentSlotNumber(nil)
628 return err
629 }); err != nil {
630 return 0, err
631 }
632 currentSlotNumber := _currentSlotNumber.Int64()
633 return currentSlotNumber, nil
634}
635
636// AuctionGetMinBidBySlot is the interface to call the smart contract function
637func (c *AuctionClient) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) {
638 var minBid *big.Int
639 if err := c.client.Call(func(ec *ethclient.Client) error {
640 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
641 if err != nil {
642 return err
643 }
644 slotToSend := big.NewInt(slot)
645 minBid, err = auction.GetMinBidBySlot(nil, slotToSend)
646 return err
647 }); err != nil {
648 return big.NewInt(0), err
649 }
650 return minBid, nil
651}
652
653// AuctionGetSlotSet is the interface to call the smart contract function
654func (c *AuctionClient) AuctionGetSlotSet(slot int64) (*big.Int, error) {
655 var slotSet *big.Int
656 if err := c.client.Call(func(ec *ethclient.Client) error {
657 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
658 if err != nil {
659 return err
660 }
661 slotToSend := big.NewInt(slot)
662 slotSet, err = auction.GetSlotSet(nil, slotToSend)
663 return err
664 }); err != nil {
665 return big.NewInt(0), err
666 }
667 return slotSet, nil
668}
669
670// AuctionGetDefaultSlotSetBid is the interface to call the smart contract function
671func (c *AuctionClient) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) {
672 var minBidSlotSet *big.Int
673 if err := c.client.Call(func(ec *ethclient.Client) error {
674 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
675 if err != nil {
676 return err
677 }
678 minBidSlotSet, err = auction.GetDefaultSlotSetBid(nil, slotSet)
679 return err
680 }); err != nil {
681 return big.NewInt(0), err
682 }
683 return minBidSlotSet, nil
684}
685
686// AuctionTokensReceived is the interface to call the smart contract function
687// func (c *AuctionClient) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error {
688// return errTODO
689// }
690
691// AuctionBid is the interface to call the smart contract function
692func (c *AuctionClient) AuctionBid(slot int64, bidAmount *big.Int, forger, tokenAddress ethCommon.Address) (*types.Transaction, error) {
693 var tx *types.Transaction
694 var err error
695 if tx, err = c.client.CallAuth(
696 c.gasLimit,
697 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
698 tokens, err := ERC777.NewERC777(tokenAddress, ec)
699 if err != nil {
700 return nil, err
701 }
702 bidFnSignature := []byte("bid(uint128,uint128,address)")
703 hash := sha3.NewLegacyKeccak256()
704 _, err = hash.Write(bidFnSignature)
705 if err != nil {
706 return nil, err
707 }
708 methodID := hash.Sum(nil)[:4]
709 slotBytes := make([]byte, 8)
710 binary.BigEndian.PutUint64(slotBytes, uint64(slot))
711 paddedSlot := ethCommon.LeftPadBytes(slotBytes, 32)
712 paddedAmount := ethCommon.LeftPadBytes(bidAmount.Bytes(), 32)
713 paddedAddress := ethCommon.LeftPadBytes(forger.Bytes(), 32)
714 var userData []byte
715 userData = append(userData, methodID...)
716 userData = append(userData, paddedSlot...)
717 userData = append(userData, paddedAmount...)
718 userData = append(userData, paddedAddress...)
719 return tokens.Send(auth, c.address, bidAmount, userData)
720 },
721 ); err != nil {
722 return nil, fmt.Errorf("Failed bid: %w", err)
723 }
724 return tx, nil
725}
726
727// AuctionMultiBid is the interface to call the smart contract function
728func (c *AuctionClient) AuctionMultiBid(startingSlot int64, endingSlot int64, slotSet [6]bool, maxBid, closedMinBid, budget *big.Int, forger, tokenAddress ethCommon.Address) (*types.Transaction, error) {
729 var tx *types.Transaction
730 var err error
731 if tx, err = c.client.CallAuth(
732 c.gasLimit,
733 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
734 tokens, err := ERC777.NewERC777(tokenAddress, ec)
735 if err != nil {
736 return nil, err
737 }
738 multiBidFnSignature := []byte("multiBid(uint128,uint128,bool[6],uint128,uint128,address)")
739 hash := sha3.NewLegacyKeccak256()
740 _, err = hash.Write(multiBidFnSignature)
741 if err != nil {
742 return nil, err
743 }
744 methodID := hash.Sum(nil)[:4]
745 startingSlotBytes := make([]byte, 8)
746 binary.BigEndian.PutUint64(startingSlotBytes, uint64(startingSlot))
747 paddedStartingSlot := ethCommon.LeftPadBytes(startingSlotBytes, 32)
748 endingSlotBytes := make([]byte, 8)
749 binary.BigEndian.PutUint64(endingSlotBytes, uint64(endingSlot))
750 paddedEndingSlot := ethCommon.LeftPadBytes(endingSlotBytes, 32)
751 paddedMinBid := ethCommon.LeftPadBytes(closedMinBid.Bytes(), 32)
752 paddedMaxBid := ethCommon.LeftPadBytes(maxBid.Bytes(), 32)
753 paddedAddress := ethCommon.LeftPadBytes(forger.Bytes(), 32)
754 var userData []byte
755 userData = append(userData, methodID...)
756 userData = append(userData, paddedStartingSlot...)
757 userData = append(userData, paddedEndingSlot...)
758 for i := 0; i < len(slotSet); i++ {
759 if slotSet[i] {
760 paddedSlotSet := ethCommon.LeftPadBytes([]byte{1}, 32)
761 userData = append(userData, paddedSlotSet...)
762 } else {
763 paddedSlotSet := ethCommon.LeftPadBytes([]byte{0}, 32)
764 userData = append(userData, paddedSlotSet...)
765 }
766 }
767 userData = append(userData, paddedMaxBid...)
768 userData = append(userData, paddedMinBid...)
769 userData = append(userData, paddedAddress...)
770 return tokens.Send(auth, c.address, budget, userData)
771 },
772 ); err != nil {
773 return nil, fmt.Errorf("Failed multibid: %w", err)
774 }
775 return tx, nil
776}
777
778// AuctionCanForge is the interface to call the smart contract function
779func (c *AuctionClient) AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error) {
780 var canForge bool
781 if err := c.client.Call(func(ec *ethclient.Client) error {
782 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
783 if err != nil {
784 return err
785 }
786 canForge, err = auction.CanForge(nil, forger, big.NewInt(blockNum))
787 return err
788 }); err != nil {
789 return false, err
790 }
791 return canForge, nil
792}
793
794// AuctionForge is the interface to call the smart contract function
795// func (c *AuctionClient) AuctionForge(forger ethCommon.Address) (bool, error) {
796// return false, errTODO
797// }
798
799// AuctionClaimHEZ is the interface to call the smart contract function
800func (c *AuctionClient) AuctionClaimHEZ(claimAddress ethCommon.Address) (*types.Transaction, error) {
801 var tx *types.Transaction
802 var err error
803 if tx, err = c.client.CallAuth(
804 c.gasLimit,
805 func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
806 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
807 if err != nil {
808 return nil, err
809 }
810 return auction.ClaimHEZ(auth, claimAddress)
811 },
812 ); err != nil {
813 return nil, fmt.Errorf("Failed claim HEZ: %w", err)
814 }
815 return tx, nil
816}
817
818// AuctionConstants returns the Constants of the Auction Smart Contract
819func (c *AuctionClient) AuctionConstants() (*AuctionConstants, error) {
820 auctionConstants := new(AuctionConstants)
821 if err := c.client.Call(func(ec *ethclient.Client) error {
822 auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
823 if err != nil {
824 return err
825 }
826 auctionConstants.BlocksPerSlot, err = auction.BLOCKSPERSLOT(nil)
827 if err != nil {
828 return err
829 }
830 genesisBlock, err := auction.GenesisBlock(nil)
831 if err != nil {
832 return err
833 }
834 auctionConstants.GenesisBlockNum = genesisBlock.Int64()
835 auctionConstants.HermezRollup, err = auction.HermezRollup(nil)
836 if err != nil {
837 return err
838 }
839 auctionConstants.InitialMinimalBidding, err = auction.INITIALMINIMALBIDDING(nil)
840 if err != nil {
841 return err
842 }
843 auctionConstants.TokenHEZ, err = auction.TokenHEZ(nil)
844 return err
845 }); err != nil {
846 return nil, err
847 }
848 return auctionConstants, nil
849}
850
851// AuctionVariables returns the variables of the Auction Smart Contract
852func (c *AuctionClient) AuctionVariables() (*AuctionVariables, error) {
853 auctionVariables := new(AuctionVariables)
854 if err := c.client.Call(func(ec *ethclient.Client) error {
855 var err error
856 auctionVariables.AllocationRatio, err = c.AuctionGetAllocationRatio()
857 if err != nil {
858 return err
859 }
860 bootCoordinator, err := c.AuctionGetBootCoordinator()
861 if err != nil {
862 return err
863 }
864 auctionVariables.BootCoordinator = *bootCoordinator
865 auctionVariables.ClosedAuctionSlots, err = c.AuctionGetClosedAuctionSlots()
866 if err != nil {
867 return err
868 }
869 var defaultSlotSetBid [6]*big.Int
870 for i := uint8(0); i < 6; i++ {
871 bid, err := c.AuctionGetDefaultSlotSetBid(i)
872 if err != nil {
873 return err
874 }
875 defaultSlotSetBid[i] = bid
876 }
877 auctionVariables.DefaultSlotSetBid = defaultSlotSetBid
878 donationAddress, err := c.AuctionGetDonationAddress()
879 if err != nil {
880 return err
881 }
882 auctionVariables.DonationAddress = *donationAddress
883 auctionVariables.OpenAuctionSlots, err = c.AuctionGetOpenAuctionSlots()
884 if err != nil {
885 return err
886 }
887 auctionVariables.Outbidding, err = c.AuctionGetOutbidding()
888 if err != nil {
889 return err
890 }
891 auctionVariables.SlotDeadline, err = c.AuctionGetSlotDeadline()
892 return err
893 }); err != nil {
894 return nil, err
895 }
896 return auctionVariables, nil
897}
898
899// AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract
900func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *ethCommon.Hash, error) {
901 log.Error("TODO")
902 return nil, nil, errTODO
903}