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.

870 lines
32 KiB

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