Skip to content

Commit

Permalink
feat: price discovery offers dont need to have a 0 price (#946)
Browse files Browse the repository at this point in the history
* feat: price discovery offers dont need to be 0 price

---------

Co-authored-by: Klemen <64400885+zajck@users.noreply.github.com>
  • Loading branch information
albertfolch-redeemeum and zajck committed May 24, 2024
1 parent b131a97 commit 4191e9f
Show file tree
Hide file tree
Showing 10 changed files with 1,676 additions and 271 deletions.
2 changes: 1 addition & 1 deletion contracts/mock/PriceDiscovery.sol
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ contract PriceDiscoveryNoTransfer is PriceDiscoveryMock {
/**
* @dev Simple bad price discovery contract used in tests
*
* This contract transfers the voucher to itself instead of the origina msg.sender
* This contract transfers the voucher to itself instead of the original msg.sender
*/
contract PriceDiscoveryTransferElsewhere is PriceDiscoveryMock, IERC721Receiver {
/**
Expand Down
30 changes: 14 additions & 16 deletions contracts/protocol/bases/OfferBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,6 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents {
// quantity must be greater than zero
if (_offer.quantityAvailable == 0) revert InvalidQuantityAvailable();

// If offer is of the discovery type, price must be zero
if (_offer.priceType == PriceType.Discovery && _offer.price != 0) revert InvalidPriceDiscoveryPrice();

DisputeResolutionTerms memory disputeResolutionTerms;
OfferFees storage offerFees = fetchOfferFees(_offer.id);
{
Expand Down Expand Up @@ -236,23 +233,24 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents {

// condition for successful payout when exchange final state is canceled
if (_offer.buyerCancelPenalty > offerPrice) revert InvalidOfferPenalty();
if (_offer.priceType == PriceType.Static) {
// Calculate and set the protocol fee
uint256 protocolFee = getProtocolFee(_offer.exchangeToken, offerPrice);

// Calculate and set the protocol fee
uint256 protocolFee = getProtocolFee(_offer.exchangeToken, offerPrice);

// Calculate the agent fee amount
uint256 agentFeeAmount = (agent.feePercentage * offerPrice) / HUNDRED_PERCENT;
// Calculate the agent fee amount
uint256 agentFeeAmount = (agent.feePercentage * offerPrice) / HUNDRED_PERCENT;

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

// 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();
// 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;
offerFees.agentFee = agentFeeAmount;
// Set offer fees props individually since calldata structs can't be copied to storage
offerFees.protocolFee = protocolFee;
offerFees.agentFee = agentFeeAmount;
}
}

// Store the agent id for the offer
Expand Down
29 changes: 16 additions & 13 deletions contracts/protocol/bases/PriceDiscoveryBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,27 @@ contract PriceDiscoveryBase is ProtocolBase {

// Set incoming voucher clone address
protocolStatus().incomingVoucherCloneAddress = address(bosonVoucher);

if (_priceDiscovery.side == Side.Ask) {
return
fulfilAskOrder(
_tokenId,
_offer.id,
_offer.exchangeToken,
_priceDiscovery,
_seller,
_buyer,
bosonVoucher
);
actualPrice = fulfilAskOrder(
_tokenId,
_offer.id,
_offer.exchangeToken,
_priceDiscovery,
_seller,
_buyer,
bosonVoucher
);
} else if (_priceDiscovery.side == Side.Bid) {
return fulfilBidOrder(_tokenId, _offer.exchangeToken, _priceDiscovery, _seller, bosonVoucher);
actualPrice = fulfilBidOrder(_tokenId, _offer.exchangeToken, _priceDiscovery, _seller, bosonVoucher);
} else {
// _priceDiscovery.side == Side.Wrapper
// Handle wrapper voucher, there is no difference between ask and bid
return handleWrapper(_tokenId, _offer.exchangeToken, _priceDiscovery, bosonVoucher);
actualPrice = handleWrapper(_tokenId, _offer.exchangeToken, _priceDiscovery, bosonVoucher);
}

// Price must be high enough to cover cancellation penalty in case of buyer's cancellation
if (actualPrice < _offer.buyerCancelPenalty) {
revert PriceDoesNotCoverPenalty();
}
}

Expand Down
16 changes: 0 additions & 16 deletions contracts/protocol/facets/OrchestrationHandlerFacet1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -145,7 +144,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -221,7 +219,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -294,7 +291,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -364,7 +360,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -433,7 +428,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -499,7 +493,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -572,7 +565,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -653,7 +645,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -740,7 +731,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -841,7 +831,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -938,7 +927,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -1038,7 +1026,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -1143,7 +1130,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -1251,7 +1237,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down Expand Up @@ -1362,7 +1347,6 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou
* - Resolution period is not between the minimum and the maximum resolution period
* - Voided is set to true
* - Available quantity is set to zero
* - Offer type is discovery and the price is not set to zero
* - Dispute resolver wallet is not registered, except for absolute zero offers with unspecified dispute resolver
* - Dispute resolver is not active, except for absolute zero offers with unspecified dispute resolver
* - Seller is not on dispute resolver's seller allow list
Expand Down
4 changes: 0 additions & 4 deletions contracts/protocol/facets/SequentialCommitHandlerFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ contract SequentialCommitHandlerFacet is IBosonSequentialCommitHandler, PriceDis
* - Reseller did not approve protocol to transfer exchange token in escrow
* - Call to price discovery contract fails
* - Protocol fee and royalties combined exceed the secondary price
* - The secondary price cannot cover the buyer's cancellation penalty
* - Transfer of exchange token fails
*
* @param _buyer - the buyer's address (caller can commit on behalf of a buyer)
Expand Down Expand Up @@ -105,9 +104,6 @@ contract SequentialCommitHandlerFacet is IBosonSequentialCommitHandler, PriceDis
// It might be lower than submitted for buy orders and higher for sell orders
thisExchangeCost.price = fulfilOrder(_tokenId, offer, _priceDiscovery, seller, _buyer);

// Price must be high enough to cover cancellation penalty in case of buyer's cancellation
if (thisExchangeCost.price < offer.buyerCancelPenalty) revert PriceDoesNotCoverPenalty();

// Get token address
address exchangeToken = offer.exchangeToken;

Expand Down
4 changes: 2 additions & 2 deletions contracts/protocol/libs/FundsLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ library FundsLib {
BosonTypes.Payoff memory payoff;

BosonTypes.OfferFees storage offerFee = pe.offerFees[exchange.offerId];
uint256 offerPrice = offer.price;
uint256 offerPrice = offer.priceType == BosonTypes.PriceType.Discovery ? 0 : offer.price;
BosonTypes.ExchangeCosts[] storage exchangeCosts = pe.exchangeCosts[_exchangeId];
uint256 lastPrice = exchangeCosts.length == 0 ? offerPrice : exchangeCosts[exchangeCosts.length - 1].price;
{
Expand Down Expand Up @@ -297,7 +297,7 @@ library FundsLib {
address msgSender = EIP712Lib.msgSender();
uint256 len = exchangeCosts.length;
for (uint256 i = 0; i < len; ) {
// Since all elements of exchangeCosts[i] are used it makes sense to copy them to memory
// Since all elements of exchangeCosts[i] are used, it makes sense to copy them to memory
BosonTypes.ExchangeCosts memory secondaryCommit = exchangeCosts[i];

// amount to be released
Expand Down
Loading

0 comments on commit 4191e9f

Please sign in to comment.