Skip to content

Commit

Permalink
Merge pull request #16 from Mint-Gold-Dust/fix/token-uri-and-memoir-i…
Browse files Browse the repository at this point in the history
…n-redeem-key

Fix/token uri and memoir in redeem key
  • Loading branch information
0xdcota authored Feb 7, 2024
2 parents 9fe4d95 + 168e4d9 commit 6dcfaa8
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 52 deletions.
44 changes: 31 additions & 13 deletions src/MgdL2NFTEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -140,24 +140,27 @@ contract MgdL2NFTEscrow is Initializable, IERC721Receiver, IERC1155Receiver {
/// @param nft token address to redeem
/// @param tokenId to redeeem
/// @param amount to redeem
/// @param owner who will receive nft
/// @param receiver who will receive nft
/// @param blockHash of tx in L2 where {MgdL2NFTVoucher.redeemVoucherToL1(...)} was called
/// @param marketData status of voucher when redeem call was initiated in L2
function getRedeemClearanceKey(
uint256 voucherId,
address nft,
uint256 tokenId,
uint256 amount,
address owner,
address receiver,
bytes32 blockHash,
MgdL1MarketData calldata marketData
MgdL1MarketData calldata marketData,
string memory tokenURI,
bytes memory tokenIdMemoir
)
external
view
returns (bool)
{
uint256 key =
_generateL1RedeemKey(voucherId, nft, tokenId, amount, owner, blockHash, marketData);
uint256 key = _generateL1RedeemKey(
voucherId, nft, tokenId, amount, receiver, blockHash, marketData, tokenURI, tokenIdMemoir
);
return redeemClearance[key];
}

Expand All @@ -180,13 +183,14 @@ contract MgdL2NFTEscrow is Initializable, IERC721Receiver, IERC1155Receiver {
address receiver,
bytes32 blockHash,
MgdL1MarketData calldata marketData,
string calldata tokenURI,
bytes calldata memoir
string memory tokenURI,
bytes memory memoir
)
external
{
uint256 key =
_generateL1RedeemKey(voucherId, nft, tokenId, amount, receiver, blockHash, marketData);
uint256 key = _generateL1RedeemKey(
voucherId, nft, tokenId, amount, receiver, blockHash, marketData, tokenURI, memoir
);
if (!redeemClearance[key]) {
revert MgdL2NFTEscrow__releaseFromEscrow_notClearedOrAlreadyReleased();
}
Expand Down Expand Up @@ -326,16 +330,30 @@ contract MgdL2NFTEscrow is Initializable, IERC721Receiver, IERC1155Receiver {
address nft,
uint256 tokenId,
uint256 amount,
address owner,
address receiver,
bytes32 blockHash,
MgdL1MarketData calldata marketData
MgdL1MarketData calldata marketData,
string memory tokenURI,
bytes memory tokenIdMemoir
)
internal
pure
returns (uint256 key)
{
key =
uint256(keccak256(abi.encode(voucherId, nft, tokenId, amount, owner, blockHash, marketData)));
if (tokenId == _REF_NUMBER) {
bytes32 hashedUriMemoir = keccak256(abi.encode(tokenURI, tokenIdMemoir));
key = uint256(
keccak256(
abi.encode(
voucherId, nft, tokenId, amount, receiver, blockHash, marketData, hashedUriMemoir
)
)
);
} else {
key = uint256(
keccak256(abi.encode(voucherId, nft, tokenId, amount, receiver, blockHash, marketData))
);
}
}

function _sendEscrowNoticeToL2(uint256 voucherId, bool state, TypeNFT nftType) internal {
Expand Down
7 changes: 4 additions & 3 deletions src/voucher/Mgd1155L2Voucher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,12 @@ contract Mgd1155L2Voucher is MgdL2BaseVoucher, ERC1155Permit, Almost1155Upgradea
_mint(owner, voucherId, representedAmount, "");

_voucherMarketData[voucherId] = marketData;
if (memoir.length > 0) {
_tokenIdMemoir[voucherId] = memoir;
}

if (generatedL1VoucherId == 0) {
_tokenURIs[voucherId] = tokenURI;
if (memoir.length > 0) {
_tokenIdMemoir[voucherId] = memoir;
}
emit MintGoldDustNFTMinted(
voucherId,
tokenURI,
Expand Down
7 changes: 4 additions & 3 deletions src/voucher/Mgd721L2Voucher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,12 @@ contract Mgd721L2Voucher is MgdL2BaseVoucher, ERC721Permit, Almost721Upgradeable
_safeMint(owner, voucherId);

_voucherMarketData[voucherId] = marketData;
if (memoir.length > 0) {
_tokenIdMemoir[voucherId] = memoir;
}

if (generatedL1VoucherId == 0) {
_tokenURIs[voucherId] = tokenURI;
if (memoir.length > 0) {
_tokenIdMemoir[voucherId] = memoir;
}
emit MintGoldDustNFTMinted(
voucherId,
tokenURI,
Expand Down
2 changes: 1 addition & 1 deletion src/voucher/MgdL2BaseNFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ abstract contract MgdL2BaseNFT is Initializable, PausableUpgradeable, Reentrancy

// voucherId => struct MgdL1MarketData
mapping(uint256 => MgdL1MarketData) internal _voucherMarketData;

mapping(uint256 => string) internal _tokenURIs;
mapping(uint256 => bytes) internal _tokenIdMemoir;

/**
Expand Down
15 changes: 13 additions & 2 deletions src/voucher/MgdL2BaseVoucher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,19 @@ abstract contract MgdL2BaseVoucher is MgdL2BaseNFT {
returns (uint256 key, bytes32 blockHash)
{
blockHash = blockhash(block.number);
key =
uint256(keccak256(abi.encode(voucherId, nft, tokenId, amount, owner, blockHash, marketData)));
if (tokenId == _REF_NUMBER) {
bytes32 hashedUriMemoir =
keccak256(abi.encode(_tokenURIs[voucherId], _tokenIdMemoir[voucherId]));
key = uint256(
keccak256(
abi.encode(voucherId, nft, tokenId, amount, owner, blockHash, marketData, hashedUriMemoir)
)
);
} else {
key = uint256(
keccak256(abi.encode(voucherId, nft, tokenId, amount, owner, blockHash, marketData))
);
}
}

function _clearVoucherData(uint256 voucherId) internal {
Expand Down
82 changes: 56 additions & 26 deletions test/foundry/RedeemingVouchersTests.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
/// Local constants: mock data to mint NFTs
string private constant _TOKEN_URI = "https://ipfs.nowhere.example/";
uint256 private constant _ROYALTY_PERCENT = 10;
string private constant _MEMOIR = "A memoir";
bytes private constant _MEMOIR = bytes("A memoir");
uint40 private constant _EDITIONS = 5;
address[4] private _COLLABS = [address(0), address(0), address(0), address(0)];
uint256[5] private _COLLABS_PERCENTAGE = [0, 0, 0, 0, 0];
Expand Down Expand Up @@ -193,11 +193,10 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan

// 8.- Mint NFTs: 2 on Ethereum and 2 on L2; 1 each for 721 and 1155
vm.startPrank(Bob.addr);
_721tokenId = nft721.mintNft(_TOKEN_URI, _ROYALTY_PERCENT, 1, bytes(_MEMOIR));
_1155tokenId = nft1155.mintNft(_TOKEN_URI, _ROYALTY_PERCENT, _EDITIONS, bytes(_MEMOIR));
nativeVoucherIdFor721 = l2voucher721.mintNft(_TOKEN_URI, _ROYALTY_PERCENT, 1, bytes(_MEMOIR));
nativeVoucherIdFor1155 =
l2voucher1155.mintNft(_TOKEN_URI, _ROYALTY_PERCENT, _EDITIONS, bytes(_MEMOIR));
_721tokenId = nft721.mintNft(_TOKEN_URI, _ROYALTY_PERCENT, 1, _MEMOIR);
_1155tokenId = nft1155.mintNft(_TOKEN_URI, _ROYALTY_PERCENT, _EDITIONS, _MEMOIR);
nativeVoucherIdFor721 = l2voucher721.mintNft(_TOKEN_URI, _ROYALTY_PERCENT, 1, _MEMOIR);
nativeVoucherIdFor1155 = l2voucher1155.mintNft(_TOKEN_URI, _ROYALTY_PERCENT, _EDITIONS, _MEMOIR);

// 9.- Transfer NFTs to escrow
vm.recordLogs();
Expand Down Expand Up @@ -338,7 +337,7 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
function test_redeemVoucher721EventsAndRedeemKey() public {
MgdL1MarketData memory marketData = l2voucher721.getVoucherMarketData(_721VId);
(uint256 expectedRedeemKey, bytes32 blockHash) =
generate_L1RedeemKey(_721VId, address(nft721), _721tokenId, 1, Bob.addr, marketData);
generate_L1RedeemKey(_721VId, address(nft721), _721tokenId, 1, Bob.addr, marketData, "", "");

bytes memory message =
abi.encodeWithSelector(MgdL2NFTEscrow.setRedeemClearanceKey.selector, expectedRedeemKey, true);
Expand All @@ -358,7 +357,7 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
function test_redeemVoucher1155EventsAndRedeemKey() public {
MgdL1MarketData memory marketData = l2voucher1155.getVoucherMarketData(_1155VId);
(uint256 expectedRedeemKey, bytes32 blockHash) = generate_L1RedeemKey(
_1155VId, address(nft1155), _1155tokenId, _EDITIONS, Bob.addr, marketData
_1155VId, address(nft1155), _1155tokenId, _EDITIONS, Bob.addr, marketData, "", ""
);

bytes memory message =
Expand Down Expand Up @@ -386,24 +385,33 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
function test_settingClearanceToRedeem() public {
MgdL1MarketData memory market721Data = l2voucher721.getVoucherMarketData(_721VId);
MgdL1MarketData memory market1155Data = l2voucher1155.getVoucherMarketData(_1155VId);
(uint256 redeem721Key, bytes32 block1155Hash) =
generate_L1RedeemKey(_721VId, address(nft721), _721tokenId, 1, Bob.addr, market721Data);
(uint256 redeem721Key, bytes32 block1155Hash) = generate_L1RedeemKey(
_721VId, address(nft721), _721tokenId, 1, Bob.addr, market721Data, "", ""
);
(uint256 redeem1155Key, bytes32 block721Hash) = generate_L1RedeemKey(
_1155VId, address(nft1155), _1155tokenId, _EDITIONS, Bob.addr, market1155Data
_1155VId, address(nft1155), _1155tokenId, _EDITIONS, Bob.addr, market1155Data, "", ""
);
vm.startPrank(L1_CROSSDOMAIN_MESSENGER);
escrow.setRedeemClearanceKey(redeem721Key, true);
escrow.setRedeemClearanceKey(redeem1155Key, true);
vm.stopPrank();
assertEq(
escrow.getRedeemClearanceKey(
_721VId, address(nft721), _721tokenId, 1, Bob.addr, block1155Hash, market721Data
_721VId, address(nft721), _721tokenId, 1, Bob.addr, block1155Hash, market721Data, "", ""
),
true
);
assertEq(
escrow.getRedeemClearanceKey(
_1155VId, address(nft1155), _1155tokenId, _EDITIONS, Bob.addr, block721Hash, market1155Data
_1155VId,
address(nft1155),
_1155tokenId,
_EDITIONS,
Bob.addr,
block721Hash,
market1155Data,
"",
""
),
true
);
Expand All @@ -412,7 +420,7 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
function test_clearanceToRedeemEvents() public {
MgdL1MarketData memory marketData = l2voucher721.getVoucherMarketData(_721VId);
(uint256 redeemKey,) =
generate_L1RedeemKey(_721VId, address(nft721), _721tokenId, 1, Bob.addr, marketData);
generate_L1RedeemKey(_721VId, address(nft721), _721tokenId, 1, Bob.addr, marketData, "", "");
vm.prank(L1_CROSSDOMAIN_MESSENGER);
vm.expectEmit(true, false, false, true, address(escrow));
emit RedeemClearanceKey(redeemKey, true);
Expand All @@ -423,10 +431,11 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
vm.assume(foe != address(0) && foe != L1_CROSSDOMAIN_MESSENGER && foe != company.owner());
MgdL1MarketData memory market721Data = l2voucher721.getVoucherMarketData(_721VId);
MgdL1MarketData memory market1155Data = l2voucher1155.getVoucherMarketData(_1155VId);
(uint256 redeem721Key,) =
generate_L1RedeemKey(_721VId, address(nft721), _721tokenId, 1, Bob.addr, market721Data);
(uint256 redeem721Key,) = generate_L1RedeemKey(
_721VId, address(nft721), _721tokenId, 1, Bob.addr, market721Data, "", ""
);
(uint256 redeem1155Key,) = generate_L1RedeemKey(
_1155VId, address(nft1155), _1155tokenId, _EDITIONS, Bob.addr, market1155Data
_1155VId, address(nft1155), _1155tokenId, _EDITIONS, Bob.addr, market1155Data, "", ""
);
vm.startPrank(foe);
vm.expectRevert(MgdL2NFTEscrow.MgdL2NFTEscrow__onlyCrossAuthorized_notAllowed.selector);
Expand All @@ -439,7 +448,7 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
function test_releaseFromEscrow721AndEvents() public {
MgdL1MarketData memory marketData = l2voucher721.getVoucherMarketData(_721VId);
(uint256 redeemKey, bytes32 blockHash) =
generate_L1RedeemKey(_721VId, address(nft721), _721tokenId, 1, Bob.addr, marketData);
generate_L1RedeemKey(_721VId, address(nft721), _721tokenId, 1, Bob.addr, marketData, "", "");
vm.prank(L1_CROSSDOMAIN_MESSENGER);
escrow.setRedeemClearanceKey(redeemKey, true);
vm.prank(Bob.addr);
Expand All @@ -455,7 +464,14 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
function test_releaseL2NativeFromEscrow721AndEvents() public {
MgdL1MarketData memory marketData = l2voucher721.getVoucherMarketData(nativeVoucherIdFor721);
(uint256 redeemKey, bytes32 blockHash) = generate_L1RedeemKey(
nativeVoucherIdFor721, address(nft721), REF_NUMBER, 1, Bob.addr, marketData
nativeVoucherIdFor721,
address(nft721),
REF_NUMBER,
1,
Bob.addr,
marketData,
_TOKEN_URI,
_MEMOIR
);
uint256 newTokenId = nft721._tokenIds() + 1;
vm.prank(L1_CROSSDOMAIN_MESSENGER);
Expand All @@ -473,7 +489,7 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
blockHash,
marketData,
_TOKEN_URI,
bytes(_MEMOIR)
_MEMOIR
);
VmSafe.Log[] memory entries721 = vm.getRecordedLogs();
uint256 resultNewTokenId = uint256(entries721[2].topics[1]);
Expand All @@ -485,7 +501,7 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
function test_releaseFromEscrow1155AndEvents() public {
MgdL1MarketData memory marketData = l2voucher1155.getVoucherMarketData(_1155VId);
(uint256 redeemKey, bytes32 blockHash) = generate_L1RedeemKey(
_1155VId, address(nft1155), _1155tokenId, _EDITIONS, Bob.addr, marketData
_1155VId, address(nft1155), _1155tokenId, _EDITIONS, Bob.addr, marketData, "", ""
);
vm.prank(L1_CROSSDOMAIN_MESSENGER);
escrow.setRedeemClearanceKey(redeemKey, true);
Expand All @@ -505,7 +521,7 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
// We override marketdata to simulate actions in L2
marketData.primarySaleL2QuantityToSell = partialAmount;
(uint256 redeemKey, bytes32 blockHash) = generate_L1RedeemKey(
_1155VId, address(nft1155), _1155tokenId, partialAmount, Bob.addr, marketData
_1155VId, address(nft1155), _1155tokenId, partialAmount, Bob.addr, marketData, "", ""
);
vm.prank(L1_CROSSDOMAIN_MESSENGER);
escrow.setRedeemClearanceKey(redeemKey, true);
Expand All @@ -532,7 +548,14 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
function test_releaseL2NativeFromEscrow1155() public {
MgdL1MarketData memory marketData = l2voucher1155.getVoucherMarketData(nativeVoucherIdFor1155);
(uint256 redeemKey, bytes32 blockHash) = generate_L1RedeemKey(
nativeVoucherIdFor1155, address(nft1155), REF_NUMBER, _EDITIONS, Bob.addr, marketData
nativeVoucherIdFor1155,
address(nft1155),
REF_NUMBER,
_EDITIONS,
Bob.addr,
marketData,
_TOKEN_URI,
_MEMOIR
);
uint256 newTokenId = nft1155._tokenIds() + 1;
vm.prank(L1_CROSSDOMAIN_MESSENGER);
Expand All @@ -552,7 +575,7 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
blockHash,
marketData,
_TOKEN_URI,
bytes(_MEMOIR)
_MEMOIR
);
VmSafe.Log[] memory entries1155 = vm.getRecordedLogs();
uint256 resultNewTokenId = uint256(entries1155[2].topics[1]);
Expand All @@ -567,7 +590,14 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
// Replace partialAmount in marketData to simulate actions in L2
marketData.primarySaleL2QuantityToSell = partialAmount;
(uint256 redeemKey, bytes32 blockHash) = generate_L1RedeemKey(
nativeVoucherIdFor1155, address(nft1155), REF_NUMBER, partialAmount, Bob.addr, marketData
nativeVoucherIdFor1155,
address(nft1155),
REF_NUMBER,
partialAmount,
Bob.addr,
marketData,
_TOKEN_URI,
_MEMOIR
);
uint256 newTokenId = nft1155._tokenIds() + 1;
vm.prank(L1_CROSSDOMAIN_MESSENGER);
Expand All @@ -587,7 +617,7 @@ contract RedeemingVoucherTests is CommonSigners, BaseL2Constants, MgdTestConstan
blockHash,
marketData,
_TOKEN_URI,
bytes(_MEMOIR)
_MEMOIR
);
VmSafe.Log[] memory entries1155 = vm.getRecordedLogs();
uint256 resultNewTokenId = uint256(entries1155[2].topics[1]);
Expand Down
Loading

0 comments on commit 6dcfaa8

Please sign in to comment.