Skip to content

Commit

Permalink
Merge branch 'main' into add-getSellerCollection-method
Browse files Browse the repository at this point in the history
  • Loading branch information
zajck authored Nov 30, 2023
2 parents a938dd8 + ed1ee1e commit 1a2b713
Show file tree
Hide file tree
Showing 32 changed files with 2,352 additions and 716 deletions.
4 changes: 3 additions & 1 deletion contracts/domain/BosonErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,10 @@ interface BosonErrors {
error InvalidQuantityAvailable();
// Chose DR does not support the fees in the chosen exchange token
error DRUnsupportedFee();
// Sum of protocol and agent fee exceed the max allowed fee
// Sum of protocol and agent fee exceeds the max allowed fee
error AgentFeeAmountTooHigh();
// Sum of protocol and agent fee exceeds the seller defined max fee
error TotalFeeExceedsLimit();
// Collection does not exist
error NoSuchCollection();
// Royalty recipient is not allow listed for the seller
Expand Down
5 changes: 5 additions & 0 deletions contracts/domain/BosonTypes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,9 @@ contract BosonTypes {
address payable[] recipients;
uint256[] bps;
}

struct PremintParameters {
uint256 reservedRangeLength;
address to;
}
}
15 changes: 10 additions & 5 deletions contracts/interfaces/handlers/IBosonOfferHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { IBosonOfferEvents } from "../events/IBosonOfferEvents.sol";
*
* @notice Handles creation, voiding, and querying of offers within the protocol.
*
* The ERC-165 identifier for this interface is: 0x7481f095
* The ERC-165 identifier for this interface is: 0xfe4be526
*/
interface IBosonOfferHandler is BosonErrors, IBosonOfferEvents {
/**
Expand Down Expand Up @@ -39,7 +39,8 @@ interface IBosonOfferHandler is BosonErrors, IBosonOfferEvents {
* - Collection does not exist
* - When agent id is non zero:
* - If Agent does not exist
* - If the sum of agent fee amount and protocol fee amount is greater than the offer fee limit
* - If the sum of agent fee amount and protocol fee amount is greater than the offer fee limit determined by the protocol
* - If the sum of agent fee amount and protocol fee amount is greater than fee limit set by seller
* - Royalty recipient is not on seller's allow list
* - Royalty percentage is less than the value decided by the admin
* - Total royalty percentage is more than max royalty percentage
Expand All @@ -49,13 +50,15 @@ interface IBosonOfferHandler is BosonErrors, IBosonOfferEvents {
* @param _offerDurations - the fully populated offer durations struct
* @param _disputeResolverId - the id of chosen dispute resolver (can be 0)
* @param _agentId - the id of agent
* @param _feeLimit - the maximum fee that seller is willing to pay per exchange (for static offers)
*/
function createOffer(
BosonTypes.Offer memory _offer,
BosonTypes.OfferDates calldata _offerDates,
BosonTypes.OfferDurations calldata _offerDurations,
uint256 _disputeResolverId,
uint256 _agentId
uint256 _agentId,
uint256 _feeLimit
) external;

/**
Expand All @@ -65,7 +68,7 @@ interface IBosonOfferHandler is BosonErrors, IBosonOfferEvents {
*
* Reverts if:
* - The offers region of protocol is paused
* - Number of elements in offers, offerDates and offerDurations do not match
* - Number of elements in offers, offerDates, offerDurations, disputeResolverIds, agentIds and feeLimits do not match
* - For any offer:
* - Caller is not an assistant
* - Valid from date is greater than valid until date
Expand Down Expand Up @@ -96,13 +99,15 @@ interface IBosonOfferHandler is BosonErrors, IBosonOfferEvents {
* @param _offerDurations - the array of fully populated offer durations structs
* @param _disputeResolverIds - the array of ids of chosen dispute resolvers (can be 0)
* @param _agentIds - the array of ids of agents
* @param _feeLimits - the array of maximum fees that seller is willing to pay per exchange (for static offers)
*/
function createOfferBatch(
BosonTypes.Offer[] calldata _offers,
BosonTypes.OfferDates[] calldata _offerDates,
BosonTypes.OfferDurations[] calldata _offerDurations,
uint256[] calldata _disputeResolverIds,
uint256[] calldata _agentIds
uint256[] calldata _agentIds,
uint256[] calldata _feeLimits
) external;

/**
Expand Down
162 changes: 97 additions & 65 deletions contracts/interfaces/handlers/IBosonOrchestrationHandler.sol

Large diffs are not rendered by default.

55 changes: 31 additions & 24 deletions contracts/protocol/bases/OfferBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents {
* - Buyer cancel penalty is greater than price
* - When agent id is non zero:
* - If Agent does not exist
* - If the sum of agent fee amount and protocol fee amount is greater than the offer fee limit
* - If the sum of agent fee amount and protocol fee amount is greater than the offer fee limit determined by the protocol
* - If the sum of agent fee amount and protocol fee amount is greater than fee limit set by seller
* - Royalty recipient is not on seller's allow list
* - Royalty percentage is less than the value decided by the admin
* - Total royalty percentage is more than max royalty percentage
Expand All @@ -47,13 +48,15 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents {
* @param _offerDurations - the fully populated offer durations struct
* @param _disputeResolverId - the id of chosen dispute resolver (can be 0)
* @param _agentId - the id of agent
* @param _feeLimit - the maximum fee that seller is willing to pay per exchange (for static offers)
*/
function createOfferInternal(
Offer memory _offer,
OfferDates calldata _offerDates,
OfferDurations calldata _offerDurations,
uint256 _disputeResolverId,
uint256 _agentId
uint256 _agentId,
uint256 _feeLimit
) internal {
// get seller id, make sure it exists and store it to incoming struct
(bool exists, uint256 sellerId) = getSellerIdByAssistant(msgSender());
Expand All @@ -64,7 +67,7 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents {
_offer.id = offerId;

// Store the offer
storeOffer(_offer, _offerDates, _offerDurations, _disputeResolverId, _agentId);
storeOffer(_offer, _offerDates, _offerDurations, _disputeResolverId, _agentId, _feeLimit);
}

/**
Expand Down Expand Up @@ -100,7 +103,8 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents {
* - Buyer cancel penalty is greater than price
* - When agent id is non zero:
* - If Agent does not exist
* - If the sum of agent fee amount and protocol fee amount is greater than the offer fee limit
* - If the sum of agent fee amount and protocol fee amount is greater than the offer fee limit determined by the protocol
* - If the sum of agent fee amount and protocol fee amount is greater than fee limit set by seller
* - Royalty recipient is not on seller's allow list
* - Royalty percentage is less than the value decided by the admin
* - Total royalty percentage is more than max royalty percentage
Expand All @@ -110,13 +114,15 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents {
* @param _offerDurations - the fully populated offer durations struct
* @param _disputeResolverId - the id of chosen dispute resolver (can be 0)
* @param _agentId - the id of agent
* @param _feeLimit - the maximum fee that seller is willing to pay per exchange (for static offers)
*/
function storeOffer(
Offer memory _offer,
OfferDates calldata _offerDates,
OfferDurations calldata _offerDurations,
uint256 _disputeResolverId,
uint256 _agentId
uint256 _agentId,
uint256 _feeLimit
) internal {
// validFrom date must be less than validUntil date
if (_offerDates.validFrom >= _offerDates.validUntil) revert InvalidOfferPeriod();
Expand All @@ -135,23 +141,6 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents {
if (_offerDurations.voucherValid == 0) revert AmbiguousVoucherExpiry();
}

// Cache protocol limits for reference
ProtocolLib.ProtocolLimits storage limits = protocolLimits();

// Operate in a block to avoid "stack too deep" error
{
// dispute period must be greater than or equal to the minimum dispute period
if (_offerDurations.disputePeriod < limits.minDisputePeriod) revert InvalidDisputePeriod();

// resolution period must be between the minimum and maximum resolution periods
if (
_offerDurations.resolutionPeriod < limits.minResolutionPeriod ||
_offerDurations.resolutionPeriod > limits.maxResolutionPeriod
) {
revert InvalidResolutionPeriod();
}
}

// when creating offer, it cannot be set to voided
if (_offer.voided) revert OfferMustBeActive();

Expand Down Expand Up @@ -213,6 +202,21 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents {
revert NoSuchCollection();
}
}
// Cache protocol limits for reference
ProtocolLib.ProtocolLimits storage limits = protocolLimits();
// Operate in a block to avoid "stack too deep" error
{
// dispute period must be greater than or equal to the minimum dispute period
if (_offerDurations.disputePeriod < limits.minDisputePeriod) revert InvalidDisputePeriod();

// resolution period must be between the minimum and maximum resolution periods
if (
_offerDurations.resolutionPeriod < limits.minResolutionPeriod ||
_offerDurations.resolutionPeriod > limits.maxResolutionPeriod
) {
revert InvalidResolutionPeriod();
}
}

// Operate in a block to avoid "stack too deep" error
{
Expand All @@ -236,8 +240,10 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents {

uint256 totalOfferFeeLimit = (limits.maxTotalOfferFeePercentage * offerPrice) / 10000;

// Sum of agent fee amount and protocol fee amount should be <= offer fee limit
if ((agentFeeAmount + protocolFee) > totalOfferFeeLimit) revert AgentFeeAmountTooHigh();
// Sum of agent fee amount and protocol fee amount should be <= offer fee limit and less that fee limit set by seller
uint256 totalFeeAmount = agentFeeAmount + protocolFee;
if (totalFeeAmount > totalOfferFeeLimit) revert AgentFeeAmountTooHigh();
if (totalFeeAmount > _feeLimit) revert TotalFeeExceedsLimit();

// Set offer fees props individually since calldata structs can't be copied to storage
offerFees.protocolFee = protocolFee;
Expand All @@ -255,6 +261,7 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents {
}
}
// Get storage location for offer

(, Offer storage offer) = fetchOffer(_offer.id);

// Set offer props individually since memory structs can't be copied to storage
Expand Down
36 changes: 25 additions & 11 deletions contracts/protocol/facets/OfferHandlerFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ contract OfferHandlerFacet is IBosonOfferHandler, OfferBase {
* - Collection does not exist
* - When agent id is non zero:
* - If Agent does not exist
* - If the sum of agent fee amount and protocol fee amount is greater than the offer fee limit
* - If the sum of agent fee amount and protocol fee amount is greater than the offer fee limit determined by the protocol
* - If the sum of agent fee amount and protocol fee amount is greater than fee limit set by seller
* - Royalty recipient is not on seller's allow list
* - Royalty percentage is less than the value decided by the admin
* - Total royalty percentage is more than max royalty percentage
Expand All @@ -56,15 +57,17 @@ contract OfferHandlerFacet is IBosonOfferHandler, OfferBase {
* @param _offerDurations - the fully populated offer durations struct
* @param _disputeResolverId - the id of chosen dispute resolver (can be 0)
* @param _agentId - the id of agent
* @param _feeLimit - the maximum fee that seller is willing to pay per exchange (for static offers)
*/
function createOffer(
Offer memory _offer,
OfferDates calldata _offerDates,
OfferDurations calldata _offerDurations,
uint256 _disputeResolverId,
uint256 _agentId
uint256 _agentId,
uint256 _feeLimit
) external override offersNotPaused nonReentrant {
createOfferInternal(_offer, _offerDates, _offerDurations, _disputeResolverId, _agentId);
createOfferInternal(_offer, _offerDates, _offerDurations, _disputeResolverId, _agentId, _feeLimit);
}

/**
Expand All @@ -74,7 +77,7 @@ contract OfferHandlerFacet is IBosonOfferHandler, OfferBase {
*
* Reverts if:
* - The offers region of protocol is paused
* - Number of elements in offers, offerDates and offerDurations do not match
* - Number of elements in offers, offerDates, offerDurations, disputeResolverIds, agentIds and feeLimits do not match
* - For any offer:
* - Caller is not an assistant
* - Valid from date is greater than valid until date
Expand All @@ -95,37 +98,48 @@ contract OfferHandlerFacet is IBosonOfferHandler, OfferBase {
* - Collection does not exist
* - When agent ids are non zero:
* - If Agent does not exist
* - If the sum of agent fee amount and protocol fee amount is greater than the offer fee limit
* - Royalty recipient is not on seller's allow list
* - Royalty percentage is less than the value decided by the admin
* - Total royalty percentage is more than max royalty percentage
* - If the sum of agent fee amount and protocol fee amount is greater than the offer fee limit determined by the protocol
* - If the sum of agent fee amount and protocol fee amount is greater than fee limit set by seller
* - Royalty recipient is not on seller's allow list
* - Royalty percentage is less than the value decided by the admin
* - Total royalty percentage is more than max royalty percentage
*
* @param _offers - the array of fully populated Offer structs with offer id set to 0x0 and voided set to false
* @param _offerDates - the array of fully populated offer dates structs
* @param _offerDurations - the array of fully populated offer durations structs
* @param _disputeResolverIds - the array of ids of chosen dispute resolvers (can be 0)
* @param _agentIds - the array of ids of agents
* @param _feeLimits - the array of maximum fees that seller is willing to pay per exchange (for static offers)
*/
function createOfferBatch(
Offer[] calldata _offers,
OfferDates[] calldata _offerDates,
OfferDurations[] calldata _offerDurations,
uint256[] calldata _disputeResolverIds,
uint256[] calldata _agentIds
uint256[] calldata _agentIds,
uint256[] calldata _feeLimits
) external override offersNotPaused nonReentrant {
// Number of offer dates structs, offer durations structs and _disputeResolverIds must match the number of offers
if (
_offers.length != _offerDates.length ||
_offers.length != _offerDurations.length ||
_offers.length != _disputeResolverIds.length ||
_offers.length != _agentIds.length
_offers.length != _agentIds.length ||
_offers.length != _feeLimits.length
) {
revert ArrayLengthMismatch();
}

for (uint256 i = 0; i < _offers.length; ) {
// Create offer and update structs values to represent true state
createOfferInternal(_offers[i], _offerDates[i], _offerDurations[i], _disputeResolverIds[i], _agentIds[i]);
createOfferInternal(
_offers[i],
_offerDates[i],
_offerDurations[i],
_disputeResolverIds[i],
_agentIds[i],
_feeLimits[i]
);

unchecked {
i++;
Expand Down
Loading

0 comments on commit 1a2b713

Please sign in to comment.