# PurchaseOfferMarket

# Overview

The Purchase Offer Market Contract tracks all purchase offers for Indexers and Consumers. It allows Consumers to create/cancel purchase offers, and Indexers to accept the purchase offer to make the service agreements. It is the place Consumer publish a purchase offer for a specific deployment. And also the place indexers can search and take these purchase offers.

# Terminology

Purchase Offer: A Purchase Offer is created by the Consumer, any Indexer can accept it to make the service agreement.

# Detail

We design the date structure for Purchase Offer, It stores purchase offer related information. A Purchase Offer can accepted by multiple Indexers. Consumer transfer Token to this contract as long as the purchase offer is created. And when Indexer accept the offer, the corresponding part of the money will transfer to serviceAgrementRegistry contract first and wait rewardDistributer contract take and distribute. After Indexer accept the offer we use the planTemplate that stored in Purchase Offer structure to generate the service agreement.

Consumers can cancel their purchase offer after expire date for free, but if cancel the unexpired Purchase Offer we will charge the penalty fee.

# PurchaseOffer

struct PurchaseOffer {
  uint256 deposit;
  uint256 minimumAcceptHeight;
  uint256 minimumStakingAmount;
  uint256 planTemplateId;
  bytes32 deploymentId;
  uint256 expireDate;
  address consumer;
  bool active;
  uint16 limit;
  uint16 numAcceptedContracts;
}

# STATES

# settings

ISettings contract which stores SubQuery network contracts address

contract ISettings settings

# offers

offerId => Offer

mapping(uint256 => struct PurchaseOfferMarket.PurchaseOffer) offers

# numOffers

number of all offers

uint256 numOffers

# penaltyRate

penalty rate of consumer cancel the unexpired offer

uint256 penaltyRate

# penaltyDestination

if penalty destination address is 0x00, then burn the penalty

address penaltyDestination

# offerPoi

offerId => Indexer => _poi

mapping(uint256 => mapping(address => bytes32)) offerPoi

# EVENTS

# PurchaseOfferCreated

Emitted when Consumer create a purchase offer

event PurchaseOfferCreated(address consumer, uint256 offerId, bytes32 deploymentId, uint256 planTemplateId, uint256 deposit, uint16 limit, uint256 minimumAcceptHeight, uint256 minimumStakingAmount, uint256 expireDate)

# PurchaseOfferCancelled

Emitted when Consumer cancel a purchase offer

event PurchaseOfferCancelled(address creator, uint256 offerId, uint256 penalty)

# OfferAccepted

Emitted when Indexer accept an offer

event OfferAccepted(address indexer, uint256 offerId, uint256 agreementId)

MODIFIER

# onlyIndexer

require caller is indexer

modifier onlyIndexer()

# initialize

Initialize this contract to set penaltyRate and penaltyDestination.

function initialize(contract ISettings _settings, uint256 _penaltyRate, address _penaltyDestination) external
Name Type Description
_settings contract ISettings ISettings contract
_penaltyRate uint256 penaltyRate that consumer cancel unexpired purchase offer
_penaltyDestination address penaltyDestination that consumer cancel unexpired purchase offer

# setSettings

Update setting state.

function setSettings(contract ISettings _settings) external
Name Type Description
_settings contract ISettings ISettings contract

# setPenaltyRate

allow admin the set the Penalty Rate for cancel unexpired offer.

function setPenaltyRate(uint256 _penaltyRate) external
Name Type Description
_penaltyRate uint256 penalty rate to set

# setPenaltyDestination

allow admin to set the Penalty Destination address. All Penalty will transfer to this address, if penalty destination address is 0x00, then burn the penalty.

function setPenaltyDestination(address _penaltyDestination) external
Name Type Description
_penaltyDestination address penalty destination to set

# createPurchaseOffer

Allow admin to create a Purchase Offer.

function createPurchaseOffer(bytes32 _deploymentId, uint256 _planTemplateId, uint256 _deposit, uint16 _limit, uint256 _minimumAcceptHeight, uint256 _minimumStakingAmount, uint256 _expireDate) external
Name Type Description
_deploymentId bytes32 deployment id
_planTemplateId uint256 plan template id
_deposit uint256 purchase offer value to deposit
_limit uint16 limit indexer to accept the purchase offer
_minimumAcceptHeight uint256 minimum block height to accept the purchase offer
_minimumStakingAmount uint256 minimum staking amount to accept the purchase offer
_expireDate uint256 expire date of the purchase offer in unix timestamp

# cancelPurchaseOffer

Allow Consumer to cancel their Purchase Offer. Consumer transfer all tokens to this contract when they create the offer. We will charge a Penalty to cancel unexpired Offer. And the Penalty will transfer to a configured address. If the address not configured, then we burn the Penalty.

function cancelPurchaseOffer(uint256 _offerId) external
Name Type Description
_offerId uint256 purchase offer id to cancel

# acceptPurchaseOffer

Allow Indexer to accept the offer and make the service agreement. The corresponding part of the money will transfer to serviceAgrementRegistry contract and wait rewardDistributer contract take and distribute as long as Indexer accept the offer. When Indexer accept the offer we need to ensure Indexer's deployment reaches the minimumAcceptHeight, So we ask indexers to pass the latest poi value when accepting the purchase offer, and save this poi value when agreement create.

function acceptPurchaseOffer(uint256 _offerId, bytes32 _poi) external
Name Type Description
_offerId uint256 purchase offer id to accept
_poi bytes32 proof of index (hash) to accept the purchase offer

# isExpired

Return the purchase offer is expired

function isExpired(uint256 _offerId) public view returns (bool)
Name Type Description
_offerId uint256 purchase offer id

Return: bool -> bool the result of is the purchase offer expired