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.

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