Skip to content

Commit

Permalink
Upgrade lsp contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
lykhonis committed Oct 28, 2023
1 parent 9e86026 commit cb6541f
Show file tree
Hide file tree
Showing 15 changed files with 61 additions and 59 deletions.
2 changes: 1 addition & 1 deletion lib/lsp-smart-contracts
17 changes: 11 additions & 6 deletions src/assets/lsp8/CollectorIdentifiableDigitalAsset.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ import {LSP8IdentifiableDigitalAssetCore} from
import {Withdrawable} from "../../common/Withdrawable.sol";
import {ICollectorIdentifiableDigitalAsset} from "./ICollectorIdentifiableDigitalAsset.sol";

bytes32 constant _LSP8_TOKEN_ID_TYPE_KEY = 0x715f248956de7ce65e94d9d836bfead479f7e70d69b718d47bfe7b00e05b4fe4;
uint256 constant _LSP8_TOKEN_ID_TYPE_NAME = 4;
uint256 constant _LSP8_TOKEN_ID_TYPE_UNIQUE_IDENTIFIER = 2;

contract CollectorIdentifiableDigitalAsset is
ICollectorIdentifiableDigitalAsset,
Expand Down Expand Up @@ -52,9 +51,15 @@ contract CollectorIdentifiableDigitalAsset is
address newOwner_,
address controller_,
uint256 tokenSupplyCap_
) LSP8IdentifiableDigitalAsset(name_, symbol_, newOwner_) LSP8CappedSupply(tokenSupplyCap_) {
)
LSP8IdentifiableDigitalAsset(name_, symbol_, newOwner_, _LSP8_TOKEN_ID_TYPE_UNIQUE_IDENTIFIER)
LSP8CappedSupply(tokenSupplyCap_)
{
_setController(controller_);
_setData(_LSP8_TOKEN_ID_TYPE_KEY, bytes.concat(bytes32(_LSP8_TOKEN_ID_TYPE_NAME)));
}

receive() external payable override(LSP8IdentifiableDigitalAsset, Withdrawable) {
_doReceive();
}

function tokenTierOf(bytes32 tokenId) external view override returns (uint8 tier) {
Expand Down Expand Up @@ -160,12 +165,12 @@ contract CollectorIdentifiableDigitalAsset is
_reservedTokenIds[index] = true;
}

function _beforeTokenTransfer(address from, address to, bytes32 tokenId)
function _beforeTokenTransfer(address from, address to, bytes32 tokenId, bytes memory data)
internal
virtual
override(LSP8IdentifiableDigitalAssetCore, LSP8Enumerable)
whenNotPaused
{
super._beforeTokenTransfer(from, to, tokenId);
super._beforeTokenTransfer(from, to, tokenId, data);
}
}
10 changes: 4 additions & 6 deletions src/assets/lsp8/MintableIdentifiableDigitalAsset.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@ import {LSP8Enumerable} from
import {LSP8CappedSupply} from
"@lukso/lsp-smart-contracts/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8CappedSupply.sol";

bytes32 constant _LSP8_TOKEN_ID_TYPE_KEY = 0x715f248956de7ce65e94d9d836bfead479f7e70d69b718d47bfe7b00e05b4fe4;

contract MintableIdentifiableDigitalAsset is LSP8Mintable, LSP8Enumerable, LSP8CappedSupply {
constructor(
string memory name_,
string memory symbol_,
address newOwner_,
uint256 tokenIdType_,
uint256 tokenSupplyCap_
) LSP8Mintable(name_, symbol_, newOwner_) LSP8CappedSupply(tokenSupplyCap_) {
_setData(_LSP8_TOKEN_ID_TYPE_KEY, abi.encodePacked(tokenIdType_));
) LSP8Mintable(name_, symbol_, newOwner_, tokenIdType_) LSP8CappedSupply(tokenSupplyCap_) {
// noop
}

function _mint(address to, bytes32 tokenId, bool allowNonLSP1Recipient, bytes memory data)
Expand All @@ -30,11 +28,11 @@ contract MintableIdentifiableDigitalAsset is LSP8Mintable, LSP8Enumerable, LSP8C
super._mint(to, tokenId, allowNonLSP1Recipient, data);
}

function _beforeTokenTransfer(address from, address to, bytes32 tokenId)
function _beforeTokenTransfer(address from, address to, bytes32 tokenId, bytes memory data)
internal
virtual
override(LSP8IdentifiableDigitalAssetCore, LSP8Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId);
super._beforeTokenTransfer(from, to, tokenId, data);
}
}
14 changes: 7 additions & 7 deletions src/common/Royalties.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,25 +84,25 @@ library Royalties {
}

RoyaltiesInfo[] memory result = new RoyaltiesInfo[](count);
uint256 i = 0;
uint256 k = 0;
uint256 j = 0;

while (i < dataLength) {
while (k < dataLength) {
uint16 length;
bytes4 interfaceId;
address recipient;
uint32 points;

assembly {
length := mload(add(add(data, 0x2), i))
interfaceId := mload(add(add(data, 0x4), add(i, 2)))
recipient := div(mload(add(add(data, 0x20), add(i, 6))), 0x1000000000000000000000000)
length := mload(add(add(data, 0x2), k))
interfaceId := mload(add(add(data, 0x4), add(k, 2)))
recipient := div(mload(add(add(data, 0x20), add(k, 6))), 0x1000000000000000000000000)
}

// optional points
if (length >= 4 /* interfaceId */ + 20 /* recipient */ + 4 /* points */ ) {
assembly {
points := mload(add(add(data, 0x4), add(i, 26)))
points := mload(add(add(data, 0x4), add(k, 26)))
}
}

Expand All @@ -111,7 +111,7 @@ library Royalties {

// skip any remaining bytes as unsupported
unchecked {
i += 2 /* length */ + length;
k += 2 /* length */ + length;
j++;
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/common/Withdrawable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ abstract contract Withdrawable is OwnableUnset {

address public beneficiary;

receive() external payable {
receive() external payable virtual {
_doReceive();
}

function _doReceive() internal virtual {
if (msg.value > 0) {
emit ValueReceived(msg.sender, msg.value);
}
Expand Down
22 changes: 5 additions & 17 deletions src/drops/LSP8DropsDigitalAsset.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ contract LSP8DropsDigitalAsset is LSP8CappedSupply, LSP8Enumerable, DropsDigital
event Minted(address indexed recipient, bytes32[] tokenIds, uint256 totalPrice);
event DefaultTokenDataChanged(bytes defaultTokenData);

error TokenTypeNotEditable();

bytes32 private constant _LSP8_TOKEN_ID_TYPE_KEY =
0x715f248956de7ce65e94d9d836bfead479f7e70d69b718d47bfe7b00e05b4fe4;
uint256 private constant _LSP8_TOKEN_ID_TYPE_COUNTER = 2;
uint256 private constant _LSP8_TOKEN_ID_TYPE_UNIQUE_NUMBER = 0;

bytes32 private constant _LSP8_TOKEN_METADATA_BASE_URI_KEY =
0x1a7628600c3bac7101f53697f48df381ddc36b9015e7d7c9c5633d1252aa2843;
Expand All @@ -39,26 +35,18 @@ contract LSP8DropsDigitalAsset is LSP8CappedSupply, LSP8Enumerable, DropsDigital
uint256 tokenSupplyCap_,
uint32 serviceFeePoints_
)
LSP8IdentifiableDigitalAsset(name_, symbol_, newOwner_)
LSP8IdentifiableDigitalAsset(name_, symbol_, newOwner_, _LSP8_TOKEN_ID_TYPE_UNIQUE_NUMBER)
LSP8CappedSupply(tokenSupplyCap_)
DropsDigitalAsset(service_, verifier_, serviceFeePoints_)
{
super._setData(_LSP8_TOKEN_ID_TYPE_KEY, bytes.concat(bytes32(_LSP8_TOKEN_ID_TYPE_COUNTER)));
// noop
}

function setDefaultTokenUri(bytes calldata newTokenUri) external onlyOwner {
defaultTokenUri = newTokenUri;
emit DefaultTokenDataChanged(newTokenUri);
}

function _setData(bytes32 dataKey, bytes memory dataValue) internal virtual override {
if (dataKey == _LSP8_TOKEN_ID_TYPE_KEY) {
revert TokenTypeNotEditable();
} else {
super._setData(dataKey, dataValue);
}
}

function _getData(bytes32 dataKey) internal view override returns (bytes memory) {
bytes memory result = super._getData(dataKey);
if ((result.length == 0) && ((dataKey & _LSP8_TOKEN_URI_DATA_KEY_PREFIX) == _LSP8_TOKEN_URI_DATA_KEY_PREFIX)) {
Expand Down Expand Up @@ -109,11 +97,11 @@ contract LSP8DropsDigitalAsset is LSP8CappedSupply, LSP8Enumerable, DropsDigital
super._mint(to, tokenId, allowNonLSP1Recipient, data);
}

function _beforeTokenTransfer(address from, address to, bytes32 tokenId)
function _beforeTokenTransfer(address from, address to, bytes32 tokenId, bytes memory data)
internal
virtual
override(LSP8IdentifiableDigitalAssetCore, LSP8Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId);
super._beforeTokenTransfer(from, to, tokenId, data);
}
}
16 changes: 10 additions & 6 deletions src/page/PageName.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import {LSP8EnumerableInitAbstract} from
"@lukso/lsp-smart-contracts/contracts/LSP8IdentifiableDigitalAsset/extensions/LSP8EnumerableInitAbstract.sol";
import {LSP8IdentifiableDigitalAssetInitAbstract} from
"@lukso/lsp-smart-contracts/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAssetInitAbstract.sol";
import {Withdrawable} from "../common/Withdrawable.sol";
import {IPageNameMarketplace, PendingSale} from "./IPageNameMarketplace.sol";

bytes32 constant _LSP8_TOKEN_ID_TYPE_KEY = 0x715f248956de7ce65e94d9d836bfead479f7e70d69b718d47bfe7b00e05b4fe4;
uint256 constant _LSP8_TOKEN_ID_TYPE_NAME = 5;
uint256 constant _LSP8_TOKEN_ID_TYPE_UNIQUE_NAME = 1;

contract PageName is LSP8EnumerableInitAbstract, ReentrancyGuardUpgradeable, PausableUpgradeable, Withdrawable {
error InvalidController();
Expand Down Expand Up @@ -51,10 +52,9 @@ contract PageName is LSP8EnumerableInitAbstract, ReentrancyGuardUpgradeable, Pau
uint16 profileLimit_,
IPageNameMarketplace marketplace_
) external initializer {
super._initialize(name_, symbol_, newOwner_);
super._initialize(name_, symbol_, newOwner_, _LSP8_TOKEN_ID_TYPE_UNIQUE_NAME);
__ReentrancyGuard_init();
__Pausable_init();
_setData(_LSP8_TOKEN_ID_TYPE_KEY, bytes.concat(bytes32(_LSP8_TOKEN_ID_TYPE_NAME)));
_setBeneficiary(beneficiary_);
_setController(controller_);
price = price_;
Expand All @@ -63,6 +63,10 @@ contract PageName is LSP8EnumerableInitAbstract, ReentrancyGuardUpgradeable, Pau
marketplace = marketplace_;
}

receive() external payable override(LSP8IdentifiableDigitalAssetInitAbstract, Withdrawable) {
_doReceive();
}

function setProfileLimit(uint16 newLimit) external onlyOwner {
profileLimit = newLimit;
}
Expand Down Expand Up @@ -146,13 +150,13 @@ contract PageName is LSP8EnumerableInitAbstract, ReentrancyGuardUpgradeable, Pau
return true;
}

function _beforeTokenTransfer(address from, address to, bytes32 tokenId)
function _beforeTokenTransfer(address from, address to, bytes32 tokenId, bytes memory data)
internal
virtual
override(LSP8EnumerableInitAbstract)
whenNotPaused
{
super._beforeTokenTransfer(from, to, tokenId);
super._beforeTokenTransfer(from, to, tokenId, data);
if (from != address(0) && to != address(0) && balanceOf(to) >= profileLimitOf(to)) {
if (msg.sender == address(marketplace)) {
PendingSale memory sale = marketplace.pendingSale();
Expand Down
9 changes: 4 additions & 5 deletions test/assets/lsp8/CollectorIdentifiableDigitalAsset.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import {
_LSP4_TOKEN_NAME_KEY,
_LSP4_TOKEN_SYMBOL_KEY
} from "@lukso/lsp-smart-contracts/contracts/LSP4DigitalAssetMetadata/LSP4Constants.sol";
import {
CollectorIdentifiableDigitalAsset,
_LSP8_TOKEN_ID_TYPE_KEY
} from "../../../src/assets/lsp8/CollectorIdentifiableDigitalAsset.sol";
import {CollectorIdentifiableDigitalAsset} from "../../../src/assets/lsp8/CollectorIdentifiableDigitalAsset.sol";
import {deployProfile} from "../../utils/profile.sol";

bytes32 constant _LSP8_TOKEN_ID_TYPE_KEY = 0x715f248956de7ce65e94d9d836bfead479f7e70d69b718d47bfe7b00e05b4fe4;

contract CollectorIdentifiableDigitalAssetTest is Test {
event TokensPurchased(address indexed recipient, bytes32[] tokenIds, uint256 totalPaid);
event TokenSupplyLimitChanged(uint256 limit);
Expand All @@ -36,7 +35,7 @@ contract CollectorIdentifiableDigitalAssetTest is Test {
function test_Initialize() public {
assertEq("Universal Page Collector", asset.getData(_LSP4_TOKEN_NAME_KEY));
assertEq("UPC", asset.getData(_LSP4_TOKEN_SYMBOL_KEY));
assertEq(4, /* unuque identifier/sequence */ uint256(bytes32(asset.getData(_LSP8_TOKEN_ID_TYPE_KEY))));
assertEq(2, /* unuque identifier/sequence */ uint256(bytes32(asset.getData(_LSP8_TOKEN_ID_TYPE_KEY))));
assertEq(0, asset.totalSupply());
assertEq(100, asset.tokenSupplyCap());
assertEq(0, asset.tokenSupplyLimit());
Expand Down
2 changes: 1 addition & 1 deletion test/marketplace/lsp8/LSP8Auctions.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ contract LSP8AuctionsTest is Test {
admin = vm.addr(1);
owner = vm.addr(2);

asset = new LSP8DigitalAssetMock("Mock", "MCK", owner);
asset = new LSP8DigitalAssetMock("Mock", "MCK", owner, 0);

listings = LSP8Listings(
address(
Expand Down
8 changes: 5 additions & 3 deletions test/marketplace/lsp8/LSP8DigitalAssetMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import {LSP8IdentifiableDigitalAsset} from
"@lukso/lsp-smart-contracts/contracts/LSP8IdentifiableDigitalAsset/LSP8IdentifiableDigitalAsset.sol";

contract LSP8DigitalAssetMock is LSP8IdentifiableDigitalAsset {
constructor(string memory name_, string memory symbol_, address newOwner_)
LSP8IdentifiableDigitalAsset(name_, symbol_, newOwner_)
{}
constructor(string memory name_, string memory symbol_, address newOwner_, uint256 tokenIdType_)
LSP8IdentifiableDigitalAsset(name_, symbol_, newOwner_, tokenIdType_)
{
// noop
}

function mint(address to, bytes32 tokenId, bool allowNonLSP1Recipient, bytes memory data) external {
_mint(to, tokenId, allowNonLSP1Recipient, data);
Expand Down
2 changes: 1 addition & 1 deletion test/marketplace/lsp8/LSP8Listings.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ contract LSP8ListingsTest is Test {
admin = vm.addr(1);
owner = vm.addr(2);

asset = new LSP8DigitalAssetMock("Mock", "MCK", owner);
asset = new LSP8DigitalAssetMock("Mock", "MCK", owner, 0);

listings = LSP8Listings(
address(
Expand Down
2 changes: 1 addition & 1 deletion test/marketplace/lsp8/LSP8Marketplace.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ contract LSP8MarketplaceTest is Test {
owner = vm.addr(2);
beneficiary = vm.addr(3);

asset = new LSP8DigitalAssetMock("Mock", "MCK", owner);
asset = new LSP8DigitalAssetMock("Mock", "MCK", owner, 0);

participant = Participant(
payable(
Expand Down
2 changes: 1 addition & 1 deletion test/marketplace/lsp8/LSP8Offers.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ contract LSP8OffersTest is Test {
admin = vm.addr(1);
owner = vm.addr(2);

asset = new LSP8DigitalAssetMock("Mock", "MCK", owner);
asset = new LSP8DigitalAssetMock("Mock", "MCK", owner, 0);

listings = LSP8Listings(
address(
Expand Down
6 changes: 4 additions & 2 deletions test/page/PageName.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import {
} from "@lukso/lsp-smart-contracts/contracts/LSP4DigitalAssetMetadata/LSP4Constants.sol";
import {UniversalProfile} from "@lukso/lsp-smart-contracts/contracts/UniversalProfile.sol";
import {IPageNameMarketplace, PendingSale} from "../../src/page/IPageNameMarketplace.sol";
import {PageName, _LSP8_TOKEN_ID_TYPE_KEY} from "../../src/page/PageName.sol";
import {PageName} from "../../src/page/PageName.sol";
import {deployProfile} from "../utils/profile.sol";
import {PageNameMarketplaceMock} from "./PageNameMarketplaceMock.sol";

bytes32 constant _LSP8_TOKEN_ID_TYPE_KEY = 0x715f248956de7ce65e94d9d836bfead479f7e70d69b718d47bfe7b00e05b4fe4;

contract PageNameTest is Test {
event ValueReceived(address indexed sender, uint256 indexed value);
event ValueWithdrawn(address indexed sender, uint256 indexed value);
Expand Down Expand Up @@ -61,7 +63,7 @@ contract PageNameTest is Test {
assertTrue(!name.paused());
assertEq("Universal Page Name", name.getData(_LSP4_TOKEN_NAME_KEY));
assertEq("UPN", name.getData(_LSP4_TOKEN_SYMBOL_KEY));
assertEq(5, /* string */ uint256(bytes32(name.getData(_LSP8_TOKEN_ID_TYPE_KEY))));
assertEq(1, /* string */ uint256(bytes32(name.getData(_LSP8_TOKEN_ID_TYPE_KEY))));
assertEq(owner, name.owner());
assertEq(beneficiary, name.beneficiary());
assertEq(controller, name.controller());
Expand Down

0 comments on commit cb6541f

Please sign in to comment.