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.

905 lines
31 KiB

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