TwoClickPurchaseSkeleton
Implementation of the Purchase skeleton facet for the TMI-Fraction Protocol.
_This facet serves as a core component (skeleton) of a TMI-Fraction Platform, enabling investors to purchase fractions from campaigns.
IMPORTANT:
-
This implementation should only be utilized by Platforms that feature campaigns issuing fungible (ERC20) fractions with discount mechanism(s). It is not recommended for campaigns with semi-fungible (ERC1155) fractions.
-
This implementation features a two (2) step process for purchasing fractions:
-
Firstly, investors purchase fractions via the
purchase()
function and receive an NFT which represents their purchase. This NFT fully represents the owner's purchase position (amount of fractions, purchased price, etc.) and acts as a receipt that can be redeemed when the campaign reaches either theFUNDED
(and its post-FUNDED
states) or theNON_FUNDED
state. The purpose of this NFT is to cater to scenarios where a campaign reaches aNON_FUNDED
state, but there have been investors who purchased at a discounted price. Since fungible fractions are indistinguishable, and there is no way to distinguish which investors purchased with a discount based on fraction balance alone, these NFTs provide a fair principal receipt mechanism (seeNonFundedSubSkeletonForTwoClick.sol
) if the campaign fails and reachesNON_FUNDED
state. -
Subsequently, owners of such NFTs (i.e., the investors) can redeem them via the
exchangeNftForFractions()
function if the associated campaign reaches itsFUNDED
state (and its post-FUNDED
states) to receive the amount of fungible fractions they are owed. This process involves burning their NFT in exchange for the respective amount of fractions that the NFT represents.
-
The first step of the purchase process is triggered when purchase()
is executed, following a sequential pipeline of six
phases:
-
State Check: The Platform interacts with its
PurchaseState
internal facet to verify that the current state of the targeted campaign is the correct state for the purchase to occur. -
Time Check: The Platform interacts with its
PurchaseTime
internal facet to verify that the current timestamp is within the campaign's configured time-window during which purchases can occur. -
Eligibility Check: The Platform interacts with its
PurchaseEligibility
internal facet to verify that the user (caller) meets the campaign's eligibility criteria to purchase fractions. -
Amount Check: The Platform interacts with its
PurchaseAmount
Internal facet to verify that the requested amount of fractions meets the campaign's constraints (e.g., hardcap etc.). -
Discount Application: The Platform interacts with its
PurchaseDiscount
internal facet to retrieve any applicable discount on the price of fractions and execute the required actions for the discount to take effect based on the provideddiscountOperationData
(e.g., burning reputation tokens in exchange for a discount), if applicable. -
Purchase Action: The Platform interacts with its
DoPurchase
internal facet to transfer the required funds from the user (caller) to the Platform. The required funds are based on either the current price (e.g., dynamic or stable) or a respective discounted price if the user has opted into any applicable discount mechanism. -
NFT Mint Action: The Platform mints an NFT to the user representing their purchase position until
FUNDED
/NON_FUNDED
states.
The second step of the purchase process of fractions is triggered when exchangeNftForFractions()
is executed, following a
sequential pipeline of four phases:
-
State Check: The Platform interacts with its
PurchaseWithExchangeStates
internal facet to verify that the current state of the targeted campaign is a correct state for the exchange to occur (redemption of NFT for fractions). -
Eligibility Check: The Platform interacts with its
PurchaseEligibility
internal facet to verify that the user (caller) meets the campaign's eligibility criteria to purchase fractions via the NFT redemption/exchange. -
NFT Burn Action: The Platform burns the NFT from the user in exchange for the respective amount of fractions it represents.
-
Post-Purchase Action: The Platform interacts with its
PostPurchase
internal facet based on the providedpostPurchaseData
to handle the purchased fractions accordingly (e.g., transferring them to the user's account or utilizing them in another supported manner, such as staking), thereby finalizing the purchase._
InvalidNftOwnerOnExchange
Thrown in exchangeNftForFractions
when the specified NFT is not owned by the caller.
NftPurchased
Emitted at purchase()
.
FractionsPurchased
Emitted at exchangeNftForFractions()
.
purchase
Executes the purchase of fractions via an intermediate NFT receipt (representing the purchase position) from a specified campaign.
_Users must meet eligibility criteria (see purchase
Eligibility internal facets) and comply
with the campaign's constraints (e.g., amount-related constraints).
Emits a {NftPurchased} event._
Parameters
Name | Type | Description |
---|---|---|
campaignId | uint256 | The unique identifier of the targeted campaign. |
amountOfFractions | uint256 | The number of fractions to purchase. |
discountOperationData | bytes | ABI-encoded data required for applying discounts (if any). |
exchangeNftForFractions
Executes the redemption of a purchase position NFT in exchange for the corresponding amount of fractions from a specified campaign.
_Users must own the NFT representing the purchase position and meet the campaign's eligibility criteria
(see purchase
Eligibility internal facets).
IMPORTANT:
- The exchange should occur only after the
campaignId
reaches itsFUNDED
andpost-FUNDED
state(s) (seePurchaseWithExchangeStates
Internal facets).
Emits a {FractionsPurchased} event._
Parameters
Name | Type | Description |
---|---|---|
campaignId | uint256 | The unique identifier of the targeted campaign. |
nftId | uint256 | The ID of the NFT representing the purchase position. |
postPurchaseData | bytes | ABI-encoded data required for the post-purchase phase. |
chainId | uint32 | The ID of the blockchain network where the purchased fractions will be received or utilized. |