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.

903 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, tokenAddress ethCommon.Address) (*types.Transaction, error)
  218. AuctionMultiBid(startingSlot int64, endingSlot int64, slotSet [6]bool, maxBid, closedMinBid, budget *big.Int, forger, tokenAddress 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. gasLimit uint64
  238. }
  239. // NewAuctionClient creates a new AuctionClient
  240. func NewAuctionClient(client *EthereumClient, address ethCommon.Address) *AuctionClient {
  241. return &AuctionClient{
  242. client: client,
  243. address: address,
  244. gasLimit: 1000000, //nolint:gomnd
  245. }
  246. }
  247. // AuctionSetSlotDeadline is the interface to call the smart contract function
  248. func (c *AuctionClient) AuctionSetSlotDeadline(newDeadline uint8) (*types.Transaction, error) {
  249. var tx *types.Transaction
  250. var err error
  251. if tx, err = c.client.CallAuth(
  252. c.gasLimit,
  253. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  254. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  255. if err != nil {
  256. return nil, err
  257. }
  258. return auction.SetSlotDeadline(auth, newDeadline)
  259. },
  260. ); err != nil {
  261. return nil, fmt.Errorf("Failed setting slotDeadline: %w", err)
  262. }
  263. return tx, nil
  264. }
  265. // AuctionGetSlotDeadline is the interface to call the smart contract function
  266. func (c *AuctionClient) AuctionGetSlotDeadline() (uint8, error) {
  267. var slotDeadline uint8
  268. if err := c.client.Call(func(ec *ethclient.Client) error {
  269. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  270. if err != nil {
  271. return err
  272. }
  273. slotDeadline, err = auction.GetSlotDeadline(nil)
  274. return err
  275. }); err != nil {
  276. return 0, err
  277. }
  278. return slotDeadline, nil
  279. }
  280. // AuctionSetOpenAuctionSlots is the interface to call the smart contract function
  281. func (c *AuctionClient) AuctionSetOpenAuctionSlots(newOpenAuctionSlots uint16) (*types.Transaction, error) {
  282. var tx *types.Transaction
  283. var err error
  284. if tx, err = c.client.CallAuth(
  285. c.gasLimit,
  286. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  287. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  288. if err != nil {
  289. return nil, err
  290. }
  291. return auction.SetOpenAuctionSlots(auth, newOpenAuctionSlots)
  292. },
  293. ); err != nil {
  294. return nil, fmt.Errorf("Failed setting openAuctionSlots: %w", err)
  295. }
  296. return tx, nil
  297. }
  298. // AuctionGetOpenAuctionSlots is the interface to call the smart contract function
  299. func (c *AuctionClient) AuctionGetOpenAuctionSlots() (uint16, error) {
  300. var openAuctionSlots uint16
  301. if err := c.client.Call(func(ec *ethclient.Client) error {
  302. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  303. if err != nil {
  304. return err
  305. }
  306. openAuctionSlots, err = auction.GetOpenAuctionSlots(nil)
  307. return err
  308. }); err != nil {
  309. return 0, err
  310. }
  311. return openAuctionSlots, nil
  312. }
  313. // AuctionSetClosedAuctionSlots is the interface to call the smart contract function
  314. func (c *AuctionClient) AuctionSetClosedAuctionSlots(newClosedAuctionSlots uint16) (*types.Transaction, error) {
  315. var tx *types.Transaction
  316. var err error
  317. if tx, err = c.client.CallAuth(
  318. c.gasLimit,
  319. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  320. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  321. if err != nil {
  322. return nil, err
  323. }
  324. return auction.SetClosedAuctionSlots(auth, newClosedAuctionSlots)
  325. },
  326. ); err != nil {
  327. return nil, fmt.Errorf("Failed setting closedAuctionSlots: %w", err)
  328. }
  329. return tx, nil
  330. }
  331. // AuctionGetClosedAuctionSlots is the interface to call the smart contract function
  332. func (c *AuctionClient) AuctionGetClosedAuctionSlots() (uint16, error) {
  333. var closedAuctionSlots uint16
  334. if err := c.client.Call(func(ec *ethclient.Client) error {
  335. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  336. if err != nil {
  337. return err
  338. }
  339. closedAuctionSlots, err = auction.GetClosedAuctionSlots(nil)
  340. return err
  341. }); err != nil {
  342. return 0, err
  343. }
  344. return closedAuctionSlots, nil
  345. }
  346. // AuctionSetOutbidding is the interface to call the smart contract function
  347. func (c *AuctionClient) AuctionSetOutbidding(newOutbidding uint16) (*types.Transaction, error) {
  348. var tx *types.Transaction
  349. var err error
  350. if tx, err = c.client.CallAuth(
  351. 12500000, //nolint:gomnd
  352. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  353. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  354. if err != nil {
  355. return nil, err
  356. }
  357. return auction.SetOutbidding(auth, newOutbidding)
  358. },
  359. ); err != nil {
  360. return nil, fmt.Errorf("Failed setting setOutbidding: %w", err)
  361. }
  362. return tx, nil
  363. }
  364. // AuctionGetOutbidding is the interface to call the smart contract function
  365. func (c *AuctionClient) AuctionGetOutbidding() (uint16, error) {
  366. var outbidding uint16
  367. if err := c.client.Call(func(ec *ethclient.Client) error {
  368. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  369. if err != nil {
  370. return err
  371. }
  372. outbidding, err = auction.GetOutbidding(nil)
  373. return err
  374. }); err != nil {
  375. return 0, err
  376. }
  377. return outbidding, nil
  378. }
  379. // AuctionSetAllocationRatio is the interface to call the smart contract function
  380. func (c *AuctionClient) AuctionSetAllocationRatio(newAllocationRatio [3]uint16) (*types.Transaction, error) {
  381. var tx *types.Transaction
  382. var err error
  383. if tx, err = c.client.CallAuth(
  384. c.gasLimit,
  385. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  386. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  387. if err != nil {
  388. return nil, err
  389. }
  390. return auction.SetAllocationRatio(auth, newAllocationRatio)
  391. },
  392. ); err != nil {
  393. return nil, fmt.Errorf("Failed setting allocationRatio: %w", err)
  394. }
  395. return tx, nil
  396. }
  397. // AuctionGetAllocationRatio is the interface to call the smart contract function
  398. func (c *AuctionClient) AuctionGetAllocationRatio() ([3]uint16, error) {
  399. var allocationRation [3]uint16
  400. if err := c.client.Call(func(ec *ethclient.Client) error {
  401. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  402. if err != nil {
  403. return err
  404. }
  405. allocationRation, err = auction.GetAllocationRatio(nil)
  406. return err
  407. }); err != nil {
  408. return [3]uint16{}, err
  409. }
  410. return allocationRation, nil
  411. }
  412. // AuctionSetDonationAddress is the interface to call the smart contract function
  413. func (c *AuctionClient) AuctionSetDonationAddress(newDonationAddress ethCommon.Address) (*types.Transaction, error) {
  414. var tx *types.Transaction
  415. var err error
  416. if tx, err = c.client.CallAuth(
  417. c.gasLimit,
  418. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  419. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  420. if err != nil {
  421. return nil, err
  422. }
  423. return auction.SetDonationAddress(auth, newDonationAddress)
  424. },
  425. ); err != nil {
  426. return nil, fmt.Errorf("Failed setting donationAddress: %w", err)
  427. }
  428. return tx, nil
  429. }
  430. // AuctionGetDonationAddress is the interface to call the smart contract function
  431. func (c *AuctionClient) AuctionGetDonationAddress() (*ethCommon.Address, error) {
  432. var donationAddress ethCommon.Address
  433. if err := c.client.Call(func(ec *ethclient.Client) error {
  434. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  435. if err != nil {
  436. return err
  437. }
  438. donationAddress, err = auction.GetDonationAddress(nil)
  439. return err
  440. }); err != nil {
  441. return nil, err
  442. }
  443. return &donationAddress, nil
  444. }
  445. // AuctionSetBootCoordinator is the interface to call the smart contract function
  446. func (c *AuctionClient) AuctionSetBootCoordinator(newBootCoordinator ethCommon.Address) (*types.Transaction, error) {
  447. var tx *types.Transaction
  448. var err error
  449. if tx, err = c.client.CallAuth(
  450. c.gasLimit,
  451. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  452. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  453. if err != nil {
  454. return nil, err
  455. }
  456. return auction.SetBootCoordinator(auth, newBootCoordinator)
  457. },
  458. ); err != nil {
  459. return nil, fmt.Errorf("Failed setting bootCoordinator: %w", err)
  460. }
  461. return tx, nil
  462. }
  463. // AuctionGetBootCoordinator is the interface to call the smart contract function
  464. func (c *AuctionClient) AuctionGetBootCoordinator() (*ethCommon.Address, error) {
  465. var bootCoordinator ethCommon.Address
  466. if err := c.client.Call(func(ec *ethclient.Client) error {
  467. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  468. if err != nil {
  469. return err
  470. }
  471. bootCoordinator, err = auction.GetBootCoordinator(nil)
  472. return err
  473. }); err != nil {
  474. return nil, err
  475. }
  476. return &bootCoordinator, nil
  477. }
  478. // AuctionChangeDefaultSlotSetBid is the interface to call the smart contract function
  479. func (c *AuctionClient) AuctionChangeDefaultSlotSetBid(slotSet int64, newInitialMinBid *big.Int) (*types.Transaction, error) {
  480. var tx *types.Transaction
  481. var err error
  482. if tx, err = c.client.CallAuth(
  483. c.gasLimit,
  484. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  485. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  486. if err != nil {
  487. return nil, err
  488. }
  489. slotSetToSend := big.NewInt(slotSet)
  490. return auction.ChangeDefaultSlotSetBid(auth, slotSetToSend, newInitialMinBid)
  491. },
  492. ); err != nil {
  493. return nil, fmt.Errorf("Failed changing slotSet Bid: %w", err)
  494. }
  495. return tx, nil
  496. }
  497. // AuctionGetClaimableHEZ is the interface to call the smart contract function
  498. func (c *AuctionClient) AuctionGetClaimableHEZ(claimAddress ethCommon.Address) (*big.Int, error) {
  499. var claimableHEZ *big.Int
  500. if err := c.client.Call(func(ec *ethclient.Client) error {
  501. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  502. if err != nil {
  503. return err
  504. }
  505. claimableHEZ, err = auction.GetClaimableHEZ(nil, claimAddress)
  506. return err
  507. }); err != nil {
  508. return nil, err
  509. }
  510. return claimableHEZ, nil
  511. }
  512. // AuctionRegisterCoordinator is the interface to call the smart contract function
  513. func (c *AuctionClient) AuctionRegisterCoordinator(forgerAddress ethCommon.Address, URL string) (*types.Transaction, error) {
  514. var tx *types.Transaction
  515. var err error
  516. if tx, err = c.client.CallAuth(
  517. c.gasLimit,
  518. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  519. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  520. if err != nil {
  521. return nil, err
  522. }
  523. return auction.RegisterCoordinator(auth, forgerAddress, URL)
  524. },
  525. ); err != nil {
  526. return nil, fmt.Errorf("Failed register coordinator: %w", err)
  527. }
  528. return tx, nil
  529. }
  530. // AuctionIsRegisteredCoordinator is the interface to call the smart contract function
  531. func (c *AuctionClient) AuctionIsRegisteredCoordinator(forgerAddress ethCommon.Address) (bool, error) {
  532. var registered bool
  533. if err := c.client.Call(func(ec *ethclient.Client) error {
  534. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  535. if err != nil {
  536. return err
  537. }
  538. registered, err = auction.IsRegisteredCoordinator(nil, forgerAddress)
  539. return err
  540. }); err != nil {
  541. return false, err
  542. }
  543. return registered, nil
  544. }
  545. // AuctionUpdateCoordinatorInfo is the interface to call the smart contract function
  546. func (c *AuctionClient) AuctionUpdateCoordinatorInfo(forgerAddress ethCommon.Address, newWithdrawAddress ethCommon.Address, newURL string) (*types.Transaction, error) {
  547. var tx *types.Transaction
  548. var err error
  549. if tx, err = c.client.CallAuth(
  550. c.gasLimit,
  551. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  552. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  553. if err != nil {
  554. return nil, err
  555. }
  556. return auction.UpdateCoordinatorInfo(auth, forgerAddress, newWithdrawAddress, newURL)
  557. },
  558. ); err != nil {
  559. return nil, fmt.Errorf("Failed update coordinator info: %w", err)
  560. }
  561. return tx, nil
  562. }
  563. // AuctionGetCurrentSlotNumber is the interface to call the smart contract function
  564. func (c *AuctionClient) AuctionGetCurrentSlotNumber() (int64, error) {
  565. var _currentSlotNumber *big.Int
  566. if err := c.client.Call(func(ec *ethclient.Client) error {
  567. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  568. if err != nil {
  569. return err
  570. }
  571. _currentSlotNumber, err = auction.GetCurrentSlotNumber(nil)
  572. return err
  573. }); err != nil {
  574. return 0, err
  575. }
  576. currentSlotNumber := _currentSlotNumber.Int64()
  577. return currentSlotNumber, nil
  578. }
  579. // AuctionGetMinBidBySlot is the interface to call the smart contract function
  580. func (c *AuctionClient) AuctionGetMinBidBySlot(slot int64) (*big.Int, error) {
  581. var minBid *big.Int
  582. if err := c.client.Call(func(ec *ethclient.Client) error {
  583. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  584. if err != nil {
  585. return err
  586. }
  587. slotToSend := big.NewInt(slot)
  588. minBid, err = auction.GetMinBidBySlot(nil, slotToSend)
  589. return err
  590. }); err != nil {
  591. return big.NewInt(0), err
  592. }
  593. return minBid, nil
  594. }
  595. // AuctionGetSlotSet is the interface to call the smart contract function
  596. func (c *AuctionClient) AuctionGetSlotSet(slot int64) (*big.Int, error) {
  597. var slotSet *big.Int
  598. if err := c.client.Call(func(ec *ethclient.Client) error {
  599. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  600. if err != nil {
  601. return err
  602. }
  603. slotToSend := big.NewInt(slot)
  604. slotSet, err = auction.GetSlotSet(nil, slotToSend)
  605. return err
  606. }); err != nil {
  607. return big.NewInt(0), err
  608. }
  609. return slotSet, nil
  610. }
  611. // AuctionGetDefaultSlotSetBid is the interface to call the smart contract function
  612. func (c *AuctionClient) AuctionGetDefaultSlotSetBid(slotSet uint8) (*big.Int, error) {
  613. var minBidSlotSet *big.Int
  614. if err := c.client.Call(func(ec *ethclient.Client) error {
  615. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  616. if err != nil {
  617. return err
  618. }
  619. minBidSlotSet, err = auction.GetDefaultSlotSetBid(nil, slotSet)
  620. return err
  621. }); err != nil {
  622. return big.NewInt(0), err
  623. }
  624. return minBidSlotSet, nil
  625. }
  626. // AuctionTokensReceived is the interface to call the smart contract function
  627. // func (c *AuctionClient) AuctionTokensReceived(operator, from, to ethCommon.Address, amount *big.Int, userData, operatorData []byte) error {
  628. // return errTODO
  629. // }
  630. // AuctionBid is the interface to call the smart contract function
  631. func (c *AuctionClient) AuctionBid(slot int64, bidAmount *big.Int, forger, tokenAddress ethCommon.Address) (*types.Transaction, error) {
  632. var tx *types.Transaction
  633. var err error
  634. if tx, err = c.client.CallAuth(
  635. c.gasLimit,
  636. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  637. tokens, err := ERC777.NewERC777(tokenAddress, ec)
  638. if err != nil {
  639. return nil, err
  640. }
  641. bidFnSignature := []byte("bid(uint128,uint128,address)")
  642. hash := sha3.NewLegacyKeccak256()
  643. _, err = hash.Write(bidFnSignature)
  644. if err != nil {
  645. return nil, err
  646. }
  647. methodID := hash.Sum(nil)[:4]
  648. slotBytes := make([]byte, 8)
  649. binary.BigEndian.PutUint64(slotBytes, uint64(slot))
  650. paddedSlot := ethCommon.LeftPadBytes(slotBytes, 32)
  651. paddedAmount := ethCommon.LeftPadBytes(bidAmount.Bytes(), 32)
  652. paddedAddress := ethCommon.LeftPadBytes(forger.Bytes(), 32)
  653. var userData []byte
  654. userData = append(userData, methodID...)
  655. userData = append(userData, paddedSlot...)
  656. userData = append(userData, paddedAmount...)
  657. userData = append(userData, paddedAddress...)
  658. return tokens.Send(auth, c.address, bidAmount, userData)
  659. },
  660. ); err != nil {
  661. return nil, fmt.Errorf("Failed bid: %w", err)
  662. }
  663. return tx, nil
  664. }
  665. // AuctionMultiBid is the interface to call the smart contract function
  666. func (c *AuctionClient) AuctionMultiBid(startingSlot int64, endingSlot int64, slotSet [6]bool, maxBid, closedMinBid, budget *big.Int, forger, tokenAddress ethCommon.Address) (*types.Transaction, error) {
  667. var tx *types.Transaction
  668. var err error
  669. if tx, err = c.client.CallAuth(
  670. c.gasLimit,
  671. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  672. tokens, err := ERC777.NewERC777(tokenAddress, ec)
  673. if err != nil {
  674. return nil, err
  675. }
  676. multiBidFnSignature := []byte("multiBid(uint128,uint128,bool[6],uint128,uint128,address)")
  677. hash := sha3.NewLegacyKeccak256()
  678. _, err = hash.Write(multiBidFnSignature)
  679. if err != nil {
  680. return nil, err
  681. }
  682. methodID := hash.Sum(nil)[:4]
  683. startingSlotBytes := make([]byte, 8)
  684. binary.BigEndian.PutUint64(startingSlotBytes, uint64(startingSlot))
  685. paddedStartingSlot := ethCommon.LeftPadBytes(startingSlotBytes, 32)
  686. endingSlotBytes := make([]byte, 8)
  687. binary.BigEndian.PutUint64(endingSlotBytes, uint64(endingSlot))
  688. paddedEndingSlot := ethCommon.LeftPadBytes(endingSlotBytes, 32)
  689. paddedMinBid := ethCommon.LeftPadBytes(closedMinBid.Bytes(), 32)
  690. paddedMaxBid := ethCommon.LeftPadBytes(maxBid.Bytes(), 32)
  691. paddedAddress := ethCommon.LeftPadBytes(forger.Bytes(), 32)
  692. var userData []byte
  693. userData = append(userData, methodID...)
  694. userData = append(userData, paddedStartingSlot...)
  695. userData = append(userData, paddedEndingSlot...)
  696. for i := 0; i < len(slotSet); i++ {
  697. if slotSet[i] {
  698. paddedSlotSet := ethCommon.LeftPadBytes([]byte{1}, 32)
  699. userData = append(userData, paddedSlotSet...)
  700. } else {
  701. paddedSlotSet := ethCommon.LeftPadBytes([]byte{0}, 32)
  702. userData = append(userData, paddedSlotSet...)
  703. }
  704. }
  705. userData = append(userData, paddedMaxBid...)
  706. userData = append(userData, paddedMinBid...)
  707. userData = append(userData, paddedAddress...)
  708. return tokens.Send(auth, c.address, budget, userData)
  709. },
  710. ); err != nil {
  711. return nil, fmt.Errorf("Failed multibid: %w", err)
  712. }
  713. return tx, nil
  714. }
  715. // AuctionCanForge is the interface to call the smart contract function
  716. func (c *AuctionClient) AuctionCanForge(forger ethCommon.Address, blockNum int64) (bool, error) {
  717. var canForge bool
  718. if err := c.client.Call(func(ec *ethclient.Client) error {
  719. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  720. if err != nil {
  721. return err
  722. }
  723. canForge, err = auction.CanForge(nil, forger, big.NewInt(blockNum))
  724. return err
  725. }); err != nil {
  726. return false, err
  727. }
  728. return canForge, nil
  729. }
  730. // AuctionForge is the interface to call the smart contract function
  731. // func (c *AuctionClient) AuctionForge(forger ethCommon.Address) (bool, error) {
  732. // return false, errTODO
  733. // }
  734. // AuctionClaimHEZ is the interface to call the smart contract function
  735. func (c *AuctionClient) AuctionClaimHEZ(claimAddress ethCommon.Address) (*types.Transaction, error) {
  736. var tx *types.Transaction
  737. var err error
  738. if tx, err = c.client.CallAuth(
  739. c.gasLimit,
  740. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  741. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  742. if err != nil {
  743. return nil, err
  744. }
  745. return auction.ClaimHEZ(auth, claimAddress)
  746. },
  747. ); err != nil {
  748. return nil, fmt.Errorf("Failed claim HEZ: %w", err)
  749. }
  750. return tx, nil
  751. }
  752. // AuctionConstants returns the Constants of the Auction Smart Contract
  753. func (c *AuctionClient) AuctionConstants() (*AuctionConstants, error) {
  754. auctionConstants := new(AuctionConstants)
  755. if err := c.client.Call(func(ec *ethclient.Client) error {
  756. auction, err := HermezAuctionProtocol.NewHermezAuctionProtocol(c.address, ec)
  757. if err != nil {
  758. return err
  759. }
  760. auctionConstants.BlocksPerSlot, err = auction.BLOCKSPERSLOT(nil)
  761. if err != nil {
  762. return err
  763. }
  764. genesisBlock, err := auction.GenesisBlock(nil)
  765. if err != nil {
  766. return err
  767. }
  768. auctionConstants.GenesisBlockNum = genesisBlock.Int64()
  769. auctionConstants.HermezRollup, err = auction.HermezRollup(nil)
  770. if err != nil {
  771. return err
  772. }
  773. auctionConstants.InitialMinimalBidding, err = auction.INITIALMINIMALBIDDING(nil)
  774. if err != nil {
  775. return err
  776. }
  777. auctionConstants.TokenHEZ, err = auction.TokenHEZ(nil)
  778. return err
  779. }); err != nil {
  780. return nil, err
  781. }
  782. return auctionConstants, nil
  783. }
  784. // AuctionVariables returns the variables of the Auction Smart Contract
  785. func (c *AuctionClient) AuctionVariables() (*AuctionVariables, error) {
  786. auctionVariables := new(AuctionVariables)
  787. if err := c.client.Call(func(ec *ethclient.Client) error {
  788. var err error
  789. auctionVariables.AllocationRatio, err = c.AuctionGetAllocationRatio()
  790. if err != nil {
  791. return err
  792. }
  793. bootCoordinator, err := c.AuctionGetBootCoordinator()
  794. if err != nil {
  795. return err
  796. }
  797. auctionVariables.BootCoordinator = *bootCoordinator
  798. auctionVariables.ClosedAuctionSlots, err = c.AuctionGetClosedAuctionSlots()
  799. if err != nil {
  800. return err
  801. }
  802. var defaultSlotSetBid [6]*big.Int
  803. for i := uint8(0); i < 6; i++ {
  804. bid, err := c.AuctionGetDefaultSlotSetBid(i)
  805. if err != nil {
  806. return err
  807. }
  808. defaultSlotSetBid[i] = bid
  809. }
  810. auctionVariables.DefaultSlotSetBid = defaultSlotSetBid
  811. donationAddress, err := c.AuctionGetDonationAddress()
  812. if err != nil {
  813. return err
  814. }
  815. auctionVariables.DonationAddress = *donationAddress
  816. auctionVariables.OpenAuctionSlots, err = c.AuctionGetOpenAuctionSlots()
  817. if err != nil {
  818. return err
  819. }
  820. auctionVariables.Outbidding, err = c.AuctionGetOutbidding()
  821. if err != nil {
  822. return err
  823. }
  824. auctionVariables.SlotDeadline, err = c.AuctionGetSlotDeadline()
  825. return err
  826. }); err != nil {
  827. return nil, err
  828. }
  829. return auctionVariables, nil
  830. }
  831. // AuctionEventsByBlock returns the events in a block that happened in the Auction Smart Contract
  832. func (c *AuctionClient) AuctionEventsByBlock(blockNum int64) (*AuctionEvents, *ethCommon.Hash, error) {
  833. log.Error("TODO")
  834. return nil, nil, errTODO
  835. }