Skip to content

Commit

Permalink
add min and max price fro the bid price per second
Browse files Browse the repository at this point in the history
  • Loading branch information
FedokDL committed Oct 25, 2024
1 parent e1cb781 commit 7574f97
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 9 deletions.
31 changes: 30 additions & 1 deletion smart-contracts/contracts/diamond/facets/Marketplace.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,15 @@ contract Marketplace is
using SafeERC20 for IERC20;
using EnumerableSet for EnumerableSet.Bytes32Set;

function __Marketplace_init(address token_) external initializer(BIDS_STORAGE_SLOT) {
function __Marketplace_init(
address token_,
uint256 bidMinPricePerSecond_,
uint256 bidMaxPricePerSecond_
) external initializer(BIDS_STORAGE_SLOT) {
BidsStorage storage bidsStorage = getBidsStorage();
bidsStorage.token = token_;

setMinMaxBidPricePerSecond(bidMinPricePerSecond_, bidMaxPricePerSecond_);
}

function setMarketplaceBidFee(uint256 bidFee_) external onlyOwner {
Expand All @@ -36,6 +42,25 @@ contract Marketplace is
emit MaretplaceFeeUpdated(bidFee_);
}

function setMinMaxBidPricePerSecond(
uint256 bidMinPricePerSecond_,
uint256 bidMaxPricePerSecond_
) public onlyOwner {
if (bidMinPricePerSecond_ == 0) {
revert MarketplaceBidMinPricePerSecondIsZero();
}

if (bidMinPricePerSecond_ > bidMaxPricePerSecond_) {
revert MarketplaceBidMinPricePerSecondIsInvalid();
}

MarketStorage storage marketStorage = getMarketStorage();
marketStorage.bidMinPricePerSecond = bidMinPricePerSecond_;
marketStorage.bidMaxPricePerSecond = bidMaxPricePerSecond_;

emit MarketplaceBidMinMaxPriceUpdated(bidMinPricePerSecond_, bidMaxPricePerSecond_);
}

function postModelBid(bytes32 modelId_, uint256 pricePerSecond_) external returns (bytes32 bidId) {
address provider_ = _msgSender();

Expand All @@ -49,6 +74,10 @@ contract Marketplace is
BidsStorage storage bidsStorage = getBidsStorage();
MarketStorage storage marketStorage = getMarketStorage();

if (pricePerSecond_ < marketStorage.bidMinPricePerSecond || pricePerSecond_ > marketStorage.bidMaxPricePerSecond) {
revert MarketplaceBidPricePerSecondInvalid();
}

IERC20(bidsStorage.token).safeTransferFrom(_msgSender(), address(this), marketStorage.bidFee);
marketStorage.feeBalance += marketStorage.bidFee;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ contract MarketplaceStorage is IMarketplaceStorage {
struct MarketStorage {
uint256 feeBalance; // Total fees balance of the contract
uint256 bidFee;
uint256 bidMinPricePerSecond;
uint256 bidMaxPricePerSecond;
}

bytes32 public constant MARKET_STORAGE_SLOT = keccak256("diamond.standard.market.storage");
Expand All @@ -20,6 +22,10 @@ contract MarketplaceStorage is IMarketplaceStorage {
return getMarketStorage().feeBalance;
}

function getMinMaxBidPricePerSecond() external view returns (uint256, uint256) {
return (getMarketStorage().bidMinPricePerSecond, getMarketStorage().bidMaxPricePerSecond);
}

/** INTERNAL */
function getMarketStorage() internal pure returns (MarketStorage storage ds) {
bytes32 slot_ = MARKET_STORAGE_SLOT;
Expand Down
19 changes: 18 additions & 1 deletion smart-contracts/contracts/interfaces/facets/IMarketplace.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,39 @@ interface IMarketplace is IMarketplaceStorage {
event MaretplaceFeeUpdated(uint256 bidFee);
event MarketplaceBidPosted(address indexed provider, bytes32 indexed modelId, uint256 nonce);
event MarketplaceBidDeleted(address indexed provider, bytes32 indexed modelId, uint256 nonce);
event MarketplaceBidMinMaxPriceUpdated(uint256 bidMinPricePerSecond, uint256 bidMaxPricePerSecond);

error MarketplaceProviderNotFound();
error MarketplaceModelNotFound();
error MarketplaceActiveBidNotFound();
error MarketplaceBidMinPricePerSecondIsZero();
error MarketplaceBidMinPricePerSecondIsInvalid();
error MarketplaceBidPricePerSecondInvalid();

/**
* The function to initialize the facet.
* @param token_ Stake token (MOR)
* @param bidMinPricePerSecond_ Min price per second for bid
* @param bidMaxPricePerSecond_ Max price per second for bid
*/
function __Marketplace_init(address token_) external;
function __Marketplace_init(address token_, uint256 bidMinPricePerSecond_, uint256 bidMaxPricePerSecond_) external;

/**
* The function to set the bidFee.
* @param bidFee_ Amount of tokens
*/
function setMarketplaceBidFee(uint256 bidFee_) external;

/**
* The function to set the min and max price per second for bid.
* @param bidMinPricePerSecond_ Min price per second for bid
* @param bidMaxPricePerSecond_ Max price per second for bid
*/
function setMinMaxBidPricePerSecond(
uint256 bidMinPricePerSecond_,
uint256 bidMaxPricePerSecond_
) external;

/**
* The function to create the bid.
* @param modelId_ The mode ID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,11 @@ interface IMarketplaceStorage {
* The function returns fee balance.
*/
function getFeeBalance() external view returns (uint256);

/**
* The function returns min and max price per second for bid.
* @return Min bid price per second
* @return Max bid price per second
*/
function getMinMaxBidPricePerSecond() external view returns (uint256, uint256);
}
31 changes: 29 additions & 2 deletions smart-contracts/test/diamond/facets/Marketplace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('Marketplace', () => {
deployFacetProviderRegistry(diamond),
deployFacetModelRegistry(diamond),
deployFacetSessionRouter(diamond, OWNER),
deployFacetMarketplace(diamond, token),
deployFacetMarketplace(diamond, token, wei(0.0001), wei(900)),
]);

await token.transfer(SECOND, wei(1000));
Expand All @@ -67,7 +67,7 @@ describe('Marketplace', () => {
expect(await marketplace.getToken()).to.eq(await token.getAddress());
});
it('should revert if try to call init function twice', async () => {
await expect(marketplace.__Marketplace_init(token)).to.be.rejectedWith(
await expect(marketplace.__Marketplace_init(token, wei(0.001), wei(0.002))).to.be.rejectedWith(
'Initializable: contract is already initialized',
);
});
Expand All @@ -89,6 +89,33 @@ describe('Marketplace', () => {
});
});

describe('#setMinMaxBidPricePerSecond', async () => {
it('should set min and max price per second', async () => {
await expect(marketplace.setMinMaxBidPricePerSecond(wei(1), wei(2)))
.to.emit(marketplace, 'MarketplaceBidMinMaxPriceUpdated')
.withArgs(wei(1), wei(2));

expect(await marketplace.getMinMaxBidPricePerSecond()).deep.eq([wei(1), wei(2)]);
});
it('should throw error when caller is not an owner', async () => {
await expect(
marketplace.connect(SECOND).setMinMaxBidPricePerSecond(wei(1), wei(2)),
).to.be.revertedWithCustomError(diamond, 'OwnableUnauthorizedAccount');
});
it('should throw error when min price is zero', async () => {
await expect(marketplace.setMinMaxBidPricePerSecond(wei(0), wei(2))).to.be.revertedWithCustomError(
marketplace,
'MarketplaceBidMinPricePerSecondIsZero',
);
});
it('should throw error when min price greater then max price', async () => {
await expect(marketplace.setMinMaxBidPricePerSecond(wei(3), wei(2))).to.be.revertedWithCustomError(
marketplace,
'MarketplaceBidMinPricePerSecondIsInvalid',
);
});
});

describe('#postModelBid', async () => {
beforeEach(async () => {
await marketplace.setMarketplaceBidFee(wei(1));
Expand Down
2 changes: 1 addition & 1 deletion smart-contracts/test/diamond/facets/ModelRegistry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('ModelRegistry', () => {
deployFacetProviderRegistry(diamond),
deployFacetModelRegistry(diamond),
deployFacetSessionRouter(diamond, OWNER),
deployFacetMarketplace(diamond, token),
deployFacetMarketplace(diamond, token, wei(0.0001), wei(900)),
]);

await token.transfer(SECOND, wei(1000));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('ProviderRegistry', () => {
deployFacetProviderRegistry(diamond),
deployFacetModelRegistry(diamond),
deployFacetSessionRouter(diamond, OWNER),
deployFacetMarketplace(diamond, token),
deployFacetMarketplace(diamond, token, wei(0.0001), wei(900)),
]);

await token.transfer(PROVIDER, wei(1000));
Expand Down
2 changes: 1 addition & 1 deletion smart-contracts/test/diamond/facets/SessionRouter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('SessionRouter', () => {
deployFacetProviderRegistry(diamond),
deployFacetModelRegistry(diamond),
deployFacetSessionRouter(diamond, FUNDING),
deployFacetMarketplace(diamond, token),
deployFacetMarketplace(diamond, token, wei(0.0001), wei(900)),
]);

await token.transfer(SECOND, wei(10000));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import {
} from '@/generated-types/ethers';
import { FacetAction } from '@/test/helpers/deployers/diamond/lumerin-diamond';

export const deployFacetMarketplace = async (diamond: LumerinDiamond, token: MorpheusToken): Promise<Marketplace> => {
export const deployFacetMarketplace = async (
diamond: LumerinDiamond,
token: MorpheusToken,
bidMinPrice: bigint,
bidMaxPrice: bigint,
): Promise<Marketplace> => {
let facet: Marketplace;

const factory = await ethers.getContractFactory('Marketplace');
Expand All @@ -34,7 +39,7 @@ export const deployFacetMarketplace = async (diamond: LumerinDiamond, token: Mor
]);

facet = facet.attach(diamond.target) as Marketplace;
await facet.__Marketplace_init(token);
await facet.__Marketplace_init(token, bidMinPrice, bidMaxPrice);

return facet;
};

0 comments on commit 7574f97

Please sign in to comment.