// SPDX-License-Identifier: MIT pragma solidity >=0.7.6 <0.8.0; /** * @title PurchaseLifeCycles * An abstract contract which define the life cycles for a purchase implementer. */ abstract contract PurchaseLifeCycles { /** * Wrapper for the purchase data passed as argument to the life cycle functions and down to their step functions. */ struct PurchaseData { address payable purchaser; address payable recipient; address token; bytes32 sku; uint256 quantity; bytes userData; uint256 totalPrice; bytes32[] pricingData; bytes32[] paymentData; bytes32[] deliveryData; } /* Internal Life Cycle Functions */ /** * `estimatePurchase` lifecycle. * @param purchase The purchase conditions. */ function _estimatePurchase(PurchaseData memory purchase) internal view virtual returns (uint256 totalPrice, bytes32[] memory pricingData) { _validation(purchase); _pricing(purchase); totalPrice = purchase.totalPrice; pricingData = purchase.pricingData; } /** * `purchaseFor` lifecycle. * @param purchase The purchase conditions. */ function _purchaseFor(PurchaseData memory purchase) internal virtual { _validation(purchase); _pricing(purchase); _payment(purchase); _delivery(purchase); _notification(purchase); } /* Internal Life Cycle Step Functions */ /** * Lifecycle step which validates the purchase pre-conditions. * @dev Responsibilities: * - Ensure that the purchase pre-conditions are met and revert if not. * @param purchase The purchase conditions. */ function _validation(PurchaseData memory purchase) internal view virtual; /** * Lifecycle step which computes the purchase price. * @dev Responsibilities: * - Computes the pricing formula, including any discount logic and price conversion; * - Set the value of `purchase.totalPrice`; * - Add any relevant extra data related to pricing in `purchase.pricingData` and document how to interpret it. * @param purchase The purchase conditions. */ function _pricing(PurchaseData memory purchase) internal view virtual; /** * Lifecycle step which manages the transfer of funds from the purchaser. * @dev Responsibilities: * - Ensure the payment reaches destination in the expected output token; * - Handle any token swap logic; * - Add any relevant extra data related to payment in `purchase.paymentData` and document how to interpret it. * @param purchase The purchase conditions. */ function _payment(PurchaseData memory purchase) internal virtual; /** * Lifecycle step which delivers the purchased SKUs to the recipient. * @dev Responsibilities: * - Ensure the product is delivered to the recipient, if that is the contract's responsibility. * - Handle any internal logic related to the delivery, including the remaining supply update; * - Add any relevant extra data related to delivery in `purchase.deliveryData` and document how to interpret it. * @param purchase The purchase conditions. */ function _delivery(PurchaseData memory purchase) internal virtual; /** * Lifecycle step which notifies of the purchase. * @dev Responsibilities: * - Manage after-purchase event(s) emission. * - Handle calls to the notifications receiver contract's `onPurchaseNotificationReceived` function, if applicable. * @param purchase The purchase conditions. */ function _notification(PurchaseData memory purchase) internal virtual; }