diff --git a/contracts/gamma/GammaCards.v3.sol b/contracts/gamma/GammaCards.v3.sol index 126bb19..83c5a94 100644 --- a/contracts/gamma/GammaCards.v3.sol +++ b/contracts/gamma/GammaCards.v3.sol @@ -229,7 +229,13 @@ contract NofGammaCardsV3 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable { if (requireOfferValidationInTransfer) { bool hasOffer = gammaOffersContract.hasOffer(msg.sender, cardNumber); - require (!hasOffer, "This card has an offer, it cannot be transfered."); + bool hasMoreThanOne = cardsByUser[msg.sender][cardNumber] > 1; + /* + The user can only make an offer for one letter and in that case he cannot mint or transfer it. + If you have more than one copy (quantity > 1) of that card, you must be able to mint + or transfer the rest. + */ + require (!hasOffer || hasMoreThanOne, "This card has an offer, it cannot be transfered."); } cardsByUser[msg.sender][cardNumber]--; @@ -244,6 +250,18 @@ contract NofGammaCardsV3 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable { require(cardsByUser[msg.sender][cardNumbers[i]] > 0, "You does not have this card."); cardsByUser[msg.sender][cardNumbers[i]]--; cardsByUser[to][cardNumbers[i]]++; + + if (requireOfferValidationInTransfer) { + bool hasOffer = gammaOffersContract.hasOffer(msg.sender, cardNumbers[i]); + bool hasMoreThanOne = cardsByUser[msg.sender][cardNumbers[i]] > 1; + /* + The user can only make an offer for one letter and in that case he cannot mint or transfer it. + If you have more than one copy (quantity > 1) of that card, you must be able to mint + or transfer the rest. + */ + require (!hasOffer || hasMoreThanOne, "This card has an offer, it cannot be transfered."); + } + } } @@ -310,7 +328,13 @@ contract NofGammaCardsV3 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable { if (requireOfferValidationInMint) { bool hasOffer = gammaOffersContract.hasOffer(msg.sender, cardNum); - require (!hasOffer, "This card has an offer, it cannot be minted."); + bool hasMoreThanOne = cardsByUser[msg.sender][cardNum] > 1; + /* + The user can only make an offer for one letter and in that case he cannot mint or transfer it. + If you have more than one copy (quantity > 1) of that card, you must be able to mint + or transfer the rest. + */ + require (!hasOffer || hasMoreThanOne, "This card has an offer, it cannot be minted."); } cardsByUser[msg.sender][cardNum]--; @@ -357,6 +381,10 @@ contract NofGammaCardsV3 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable { return cardsByUser[msg.sender][cardNum] > 0; } + function getCardQuantityByUser(address user, uint8 cardNum) public view returns (uint8) { + return cardsByUser[user][cardNum]; + } + function getCardsByUser(address user) public view returns (uint8[] memory, uint8[] memory, bool[] memory) { uint8[] memory cardNumbers = new uint8[](121); uint8[] memory quantities = new uint8[](121); diff --git a/test/gamma.cards.test.ts b/test/gamma.cards.test.ts index e8a8a11..ba63d8d 100644 --- a/test/gamma.cards.test.ts +++ b/test/gamma.cards.test.ts @@ -102,6 +102,26 @@ describe('NoF - Gamma Cards Tests', function () { await gammaCards.mintCard(getCardsByUserResult[0][0]); }); + it('should allow to mint a card when has an offer, qantity > 1 and flag requireOfferValidationInMint is true', async () => { + const { gammaPacks, gammaCards, gammaOffers, address0 } = await loadFixture(deployNofFixture) + const getCardsByUserResult1: getCardsByUserType = await getOnePackData(gammaPacks, gammaCards, address0) + // another pack with the same cards. + await getOnePackData(gammaPacks, gammaCards, address0) + + const cardNumber = getCardsByUserResult1[0][0]; + let quantity = await gammaCards.getCardQuantityByUser(address0.address, cardNumber); + await expect(quantity).to.be.equal(2); + + await gammaOffers.createOffer(cardNumber, [1,2,24,4,5,6,7,8]) + let offers = await gammaOffers.getOffers(); + await expect(offers.length).to.not.be.equal(0); + + await gammaCards.changeRequireOfferValidationInMint(true); + await gammaCards.mintCard(cardNumber); + quantity = await gammaCards.getCardQuantityByUser(address0.address, cardNumber); + await expect(quantity).to.be.equal(1); + }); + it('should not allow to transfer a card when has an offer and flag requireOfferValidationInTransfer is true', async () => { const { gammaPacks, gammaCards, gammaOffers, address0, address1 } = await loadFixture(deployNofFixture) const getCardsByUserResult: getCardsByUserType = await getOnePackData(gammaPacks, gammaCards, address0) @@ -117,12 +137,11 @@ describe('NoF - Gamma Cards Tests', function () { ).to.be.revertedWith('This card has an offer, it cannot be transfered.') }); - it('should allow to mint a card when has an offer and flag requireOfferValidationInTransfer is false', async () => { + it('should allow to transfer a card when has an offer and flag requireOfferValidationInTransfer is false', async () => { const { gammaPacks, gammaCards, gammaOffers, address0, address1 } = await loadFixture(deployNofFixture) const getCardsByUserResult: getCardsByUserType = await getOnePackData(gammaPacks, gammaCards, address0) await gammaOffers.createOffer(getCardsByUserResult[0][0], [1,2,24,4,5,6,7,8]) - let offers = await gammaOffers.getOffers(); await expect(offers.length).to.not.be.equal(0); @@ -130,5 +149,42 @@ describe('NoF - Gamma Cards Tests', function () { await gammaCards.transferCard(address1.address, getCardsByUserResult[0][0]); }); + it('should allow to transfer a card when has an offer, qantity > 1 and flag requireOfferValidationInTransfer is true', async () => { + const { gammaPacks, gammaCards, gammaOffers, address0, address1 } = await loadFixture(deployNofFixture) + const getCardsByUserResult1: getCardsByUserType = await getOnePackData(gammaPacks, gammaCards, address0) + // another pack with the same cards. + await getOnePackData(gammaPacks, gammaCards, address0) + + const cardNumber = getCardsByUserResult1[0][0]; + let quantity = await gammaCards.getCardQuantityByUser(address0.address, cardNumber); + await expect(quantity).to.be.equal(2); + + await gammaOffers.createOffer(cardNumber, [1,2,24,4,5,6,7,8]) + let offers = await gammaOffers.getOffers(); + await expect(offers.length).to.not.be.equal(0); + + await gammaCards.changeRequireOfferValidationInTransfer(true); + await gammaCards.transferCard(address1.address, cardNumber); + quantity = await gammaCards.getCardQuantityByUser(address0.address, cardNumber); + await expect(quantity).to.be.equal(1); + }); + + it('should allow to transfer several cards', async () => { + const { gammaPacks, gammaCards, gammaOffers, address0, address1 } = await loadFixture(deployNofFixture) + const getCardsByUserResult1: getCardsByUserType = await getOnePackData(gammaPacks, gammaCards, address0) + + const cardNumber1 = getCardsByUserResult1[0][0]; + const cardNumber2 = getCardsByUserResult1[0][1]; + const cardNumber3 = getCardsByUserResult1[0][2]; + const cards = [cardNumber1, cardNumber2, cardNumber3]; + + await gammaCards.transferCards(address1.address, cards); + const quantity1 = await gammaCards.getCardQuantityByUser(address0.address, cardNumber1); + const quantity2 = await gammaCards.getCardQuantityByUser(address0.address, cardNumber2); + const quantity3 = await gammaCards.getCardQuantityByUser(address0.address, cardNumber3); + await expect(quantity1).to.be.equal(0); + await expect(quantity2).to.be.equal(0); + await expect(quantity3).to.be.equal(0); + }); })