Skip to content

Commit

Permalink
Restrict lsp7
Browse files Browse the repository at this point in the history
  • Loading branch information
lykhonis committed Jan 25, 2024
1 parent 022d23a commit 65bdb1c
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 8 deletions.
26 changes: 21 additions & 5 deletions src/marketplace/lsp7/LSP7Listings.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity =0.8.22;

import {
_LSP4_TOKEN_TYPE_KEY,
_LSP4_TOKEN_TYPE_NFT
} from "@lukso/lsp-smart-contracts/contracts/LSP4DigitalAssetMetadata/LSP4Constants.sol";
import {ILSP7DigitalAsset} from "@lukso/lsp-smart-contracts/contracts/LSP7DigitalAsset/ILSP7DigitalAsset.sol";
import {Module} from "../common/Module.sol";
import {ILSP7Listings, LSP7Listing} from "./ILSP7Listings.sol";
Expand All @@ -14,6 +18,7 @@ contract LSP7Listings is ILSP7Listings, Module {
error InactiveListing(uint256 id);
error InvalidDeduction(uint256 available, uint256 deducted);
error InvalidListingAmount(uint256 total, uint256 authorizedAllowance);
error InvalidListingType(address asset, uint256 lsp4TokenType, bool isNonDivisible);

uint256 public totalListings;
mapping(uint256 => LSP7Listing) private _listings;
Expand Down Expand Up @@ -55,17 +60,28 @@ contract LSP7Listings is ILSP7Listings, Module {
if (itemCount == 0) {
revert InvalidListingZeroItems();
}
// verify that the asset is a non-divisible NFT
{
uint256 tokenType = uint256(bytes32(ILSP7DigitalAsset(asset).getData(_LSP4_TOKEN_TYPE_KEY)));
bool divisible = ILSP7DigitalAsset(asset).decimals() != 0;
if (tokenType != _LSP4_TOKEN_TYPE_NFT || divisible) {
revert InvalidListingType(asset, tokenType, !divisible);
}
}
address seller = msg.sender;
uint256 allowance = ILSP7DigitalAsset(asset).authorizedAmountFor(seller, owner);
if (allowance < itemCount) {
revert InsufficientAuthorization(seller, itemCount, allowance);
}
bytes32 key = _listingKey(asset, owner);
uint256 listedAmount = _listedAmount[key] + itemCount;
if (listedAmount > allowance) {
revert InvalidListingAmount(listedAmount, allowance);
// verify that the listing is valid
{
bytes32 key = _listingKey(asset, owner);
uint256 listedAmount = _listedAmount[key] + itemCount;
if (listedAmount > allowance) {
revert InvalidListingAmount(listedAmount, allowance);
}
_listedAmount[key] = listedAmount;
}
_listedAmount[key] = listedAmount;
totalListings += 1;
uint256 id = totalListings;
uint256 endTime = 0;
Expand Down
37 changes: 36 additions & 1 deletion test/marketplace/lsp7/LSP7Listings.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import {
TransparentUpgradeableProxy
} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {UniversalProfile} from "@lukso/lsp-smart-contracts/contracts/UniversalProfile.sol";
import {
_LSP4_TOKEN_TYPE_TOKEN,
_LSP4_TOKEN_TYPE_NFT,
_LSP4_TOKEN_TYPE_COLLECTION
} from "@lukso/lsp-smart-contracts/contracts/LSP4DigitalAssetMetadata/LSP4Constants.sol";
import {OwnableCallerNotTheOwner} from "@erc725/smart-contracts/contracts/errors.sol";
import {Module, MARKETPLACE_ROLE} from "../../../src/marketplace/common/Module.sol";
import {LSP7Listings, LSP7Listing} from "../../../src/marketplace/lsp7/LSP7Listings.sol";
Expand Down Expand Up @@ -45,7 +50,7 @@ contract LSP7ListingsTest is Test {
admin = vm.addr(1);
owner = vm.addr(2);

asset = new LSP7DigitalAssetMock("Mock", "MCK", owner, 0, true);
asset = new LSP7DigitalAssetMock("Mock", "MCK", owner, _LSP4_TOKEN_TYPE_NFT, true);

listings = LSP7Listings(
address(
Expand Down Expand Up @@ -459,4 +464,34 @@ contract LSP7ListingsTest is Test {
vm.expectRevert(abi.encodeWithSelector(LSP7Listings.InvalidListingAmount.selector, 11, 10));
listings.list(address(asset), address(profile), 4, 1 ether, block.timestamp, 10 days);
}

function test_Revert_ListDivisibleNft() public {
LSP7DigitalAssetMock invalidAsset = new LSP7DigitalAssetMock("Mock", "MCK", owner, _LSP4_TOKEN_TYPE_NFT, false);

(UniversalProfile profile,) = deployProfile();
invalidAsset.mint(address(profile), 10, false, "");

vm.prank(address(profile));
vm.expectRevert(
abi.encodeWithSelector(
LSP7Listings.InvalidListingType.selector, address(invalidAsset), _LSP4_TOKEN_TYPE_NFT, false
)
);
listings.list(address(invalidAsset), address(profile), 10, 1 ether, block.timestamp, 10 days);
}

function test_Revert_ListNonNft() public {
LSP7DigitalAssetMock invalidAsset = new LSP7DigitalAssetMock("Mock", "MCK", owner, _LSP4_TOKEN_TYPE_TOKEN, true);

(UniversalProfile profile,) = deployProfile();
invalidAsset.mint(address(profile), 10, false, "");

vm.prank(address(profile));
vm.expectRevert(
abi.encodeWithSelector(
LSP7Listings.InvalidListingType.selector, address(invalidAsset), _LSP4_TOKEN_TYPE_TOKEN, true
)
);
listings.list(address(invalidAsset), address(profile), 10, 1 ether, block.timestamp, 10 days);
}
}
3 changes: 2 additions & 1 deletion test/marketplace/lsp7/LSP7Marketplace.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {_INTERFACEID_LSP0} from "@lukso/lsp-smart-contracts/contracts/LSP0ERC725Account/LSP0Constants.sol";
import {UniversalProfile} from "@lukso/lsp-smart-contracts/contracts/UniversalProfile.sol";
import {_LSP4_TOKEN_TYPE_NFT} from "@lukso/lsp-smart-contracts/contracts/LSP4DigitalAssetMetadata/LSP4Constants.sol";
import {OwnableCallerNotTheOwner} from "@erc725/smart-contracts/contracts/errors.sol";
import {Module, MARKETPLACE_ROLE} from "../../../src/marketplace/common/Module.sol";
import {Points} from "../../../src/common/Points.sol";
Expand Down Expand Up @@ -51,7 +52,7 @@ contract LSP7MarketplaceTest is Test {
owner = vm.addr(2);
beneficiary = vm.addr(3);

asset = new LSP7DigitalAssetMock("Mock", "MCK", owner, 0, true);
asset = new LSP7DigitalAssetMock("Mock", "MCK", owner, _LSP4_TOKEN_TYPE_NFT, true);

participant = Participant(
payable(
Expand Down
3 changes: 2 additions & 1 deletion test/marketplace/lsp7/LSP7Offers.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
TransparentUpgradeableProxy
} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {UniversalProfile} from "@lukso/lsp-smart-contracts/contracts/UniversalProfile.sol";
import {_LSP4_TOKEN_TYPE_NFT} from "@lukso/lsp-smart-contracts/contracts/LSP4DigitalAssetMetadata/LSP4Constants.sol";
import {OwnableCallerNotTheOwner} from "@erc725/smart-contracts/contracts/errors.sol";
import {Module, MARKETPLACE_ROLE} from "../../../src/marketplace/common/Module.sol";
import {LSP7Listings, LSP7Listing} from "../../../src/marketplace/lsp7/LSP7Listings.sol";
Expand All @@ -31,7 +32,7 @@ contract LSP7OffersTest is Test {
admin = vm.addr(1);
owner = vm.addr(2);

asset = new LSP7DigitalAssetMock("Mock", "MCK", owner, 0, true);
asset = new LSP7DigitalAssetMock("Mock", "MCK", owner, _LSP4_TOKEN_TYPE_NFT, true);

listings = LSP7Listings(
address(
Expand Down

0 comments on commit 65bdb1c

Please sign in to comment.