Skip to content

Commit

Permalink
Merge pull request #116 from P4-Games/feature/115-burn-with-offer
Browse files Browse the repository at this point in the history
[feat] 🦺 check if user has enough copies to burn with off…
  • Loading branch information
dappsar authored Dec 29, 2023
2 parents 59dda48 + 86773c9 commit ed03e47
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 27 deletions.
37 changes: 21 additions & 16 deletions contracts/gamma/GammaCards.v5.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface IgammaPacksContract {
interface IgammaOffersContract {
function hasOffer(address user, uint8 cardNumber) external view returns (bool);
function removeOffersByUser(address user) external returns (bool);
function getOffersByUserCounter(address user) external view returns (uint256);
function getOfferByUserAndCardNumber(address user, uint8 cardNumber) external view
returns (uint256, uint8, uint8[] memory , address);
}
Expand Down Expand Up @@ -112,7 +113,7 @@ contract NofGammaCardsV5 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
secondaryUri = string(abi.encodePacked(bytes(baseUri), bytes("/"), bytes("121"), bytes("F.json")));
signersData.signers[_signer] = true;

for(uint256 i;i<122;i++){
for(uint256 i; i<122; i++){
cardsInventory[i] = 1;
}
}
Expand Down Expand Up @@ -170,11 +171,7 @@ contract NofGammaCardsV5 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
lotteryPrizePercentage = amount;
}

function getLotteryPrize() public view returns (uint256) {
return (lotteryPrizePercentage * prizesBalance) / 100;
}

function setUris(string memory newMainUri, string memory newSecondaryUri) public onlyOwners {
function setUris(string memory newMainUri, string memory newSecondaryUri) external onlyOwners {
mainUri = newMainUri;
secondaryUri = newSecondaryUri;
emit NewUris(newMainUri, newSecondaryUri);
Expand Down Expand Up @@ -225,6 +222,10 @@ contract NofGammaCardsV5 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
return signersData.signers[user];
}

function getLotteryPrize() public view returns (uint256) {
return (lotteryPrizePercentage * prizesBalance) / 100;
}

function getCardQuantityByUser(address user, uint8 cardNum) public view returns (uint8) {
require(user != address(0), "Invalid address.");
return cardsByUser[user][cardNum];
Expand Down Expand Up @@ -296,7 +297,7 @@ contract NofGammaCardsV5 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
gammaPacksContract.openPack(packNumber, user);
prizesBalance += packPrice - packPrice / 6;

for(uint8 i;i<packData.length;i++){
for(uint8 i; i<packData.length; i++){
require(packData[i] == 120 ? cardsInventory[120] < 3001 : cardsInventory[packData[i]] < 5001,
'invalid cardInventory position');
cardsInventory[packData[i]]++; // 280k gas aprox.
Expand Down Expand Up @@ -377,10 +378,8 @@ contract NofGammaCardsV5 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
require(contractBalance >= mainAlbumPrize, "Insufficient funds (contract).");

// check that you have at least one card of each number
// TO-REVIEW: check if this part is necessary because the subtraction of cards
// would cause underflow if it is at 0
bool unfinished;
for(uint8 i;i<=120;i++){
for(uint8 i; i<=120; i++){
if(cardsByUser[msg.sender][i] == 0) {
unfinished = true;
break;
Expand All @@ -407,23 +406,29 @@ contract NofGammaCardsV5 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
// the 60 cards album to 'burn' them.
function burnCards(uint8[] calldata cardNumbers) public {
require(cardsByUser[msg.sender][121] > 0, "You does not have any burning album.");

uint256 totalUserBurnedCards = burnedCards[msg.sender] + cardNumbers.length;
bool mustPayPrize = false;

if (totalUserBurnedCards >= 60) {
require(prizesBalance >= secondaryAlbumPrize, "Insufficient funds (burnCards balance).");

uint256 contractBalance = IERC20(DAI_TOKEN).balanceOf(address(this));
require(contractBalance >= secondaryAlbumPrize, "Insufficient funds (contract).");

mustPayPrize = true;
}

for(uint8 i;i<cardNumbers.length;i++){
bool userHasOffers = (gammaOffersContract.getOffersByUserCounter(msg.sender) > 0);
for(uint8 i; i<cardNumbers.length; i++){
require(cardsByUser[msg.sender][cardNumbers[i]] > 0, "You does not have this card.");
if (userHasOffers) {

if (gammaOffersContract.hasOffer(msg.sender, cardNumbers[i])) {
require(cardsByUser[msg.sender][cardNumbers[i]] >= 2,
"You cannot burn any more copies of this card.");
}
}
cardsByUser[msg.sender][cardNumbers[i]]--;
}

burnedCards[msg.sender] += cardNumbers.length;
emit CardsBurned(msg.sender, cardNumbers);

Expand Down Expand Up @@ -473,7 +478,7 @@ contract NofGammaCardsV5 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
}

function testAddCards(address user) public onlyOwners {
for(uint8 i;i<=121;i++){ // 0-119: cards, 120: album-120, 121: album-60
for(uint8 i; i<=121; i++){ // 0-119: cards, 120: album-120, 121: album-60
cardsByUser[user][i]++;
}
}
Expand All @@ -482,7 +487,7 @@ contract NofGammaCardsV5 is ERC721, ERC721URIStorage, ERC721Burnable, Ownable {
gammaPacksContract.openPack(packNumber, user);
prizesBalance += packPrice - packPrice / 6;

for(uint8 i;i<packData.length;i++){
for(uint8 i; i<packData.length; i++){
require(packData[i] == 120 ? cardsInventory[120] < 3001 : cardsInventory[packData[i]] < 5001,
'invalid cardInventory position');
cardsInventory[packData[i]]++; // 280k gas aprox.
Expand Down
1 change: 0 additions & 1 deletion contracts/gamma/GammaOffers.v4.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ contract NofGammaOffersV4 is Ownable {
using LibControlMgmt for LibControlMgmt.Data;

IGammaCardsContract public gammaCardsContract;

LibControlMgmt.Data private ownersData;

uint256 maxOffersAllowed = uint256(5000);
Expand Down
88 changes: 78 additions & 10 deletions test/gamma.cards.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ describe('NoF - Gamma Cards Tests', function () {

await gammaOffers.createOffer(uuidv4(), cardNumber, [1, 2, 24, 4, 5, 6, 7, 8])
let offers = await gammaOffers.getOffers()
await expect(offers.length).to.not.be.equal(0)
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)
expect(quantity).to.be.equal(1)
})

it('Should not allow the transfer a card when has an offer and flag requireOfferValidationInTransfer is true', async () => {
Expand All @@ -131,7 +131,7 @@ describe('NoF - Gamma Cards Tests', function () {
await gammaOffers.createOffer(uuidv4(), 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)
expect(offers.length).to.not.be.equal(0)

await gammaCards.changeRequireOfferValidationInTransfer(true)
await expect(gammaCards.transferCard(address1.address, getCardsByUserResult[0][0])).to.be.revertedWith(
Expand All @@ -145,7 +145,7 @@ describe('NoF - Gamma Cards Tests', function () {

await gammaOffers.createOffer(uuidv4(), 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)
expect(offers.length).to.not.be.equal(0)

await gammaCards.changeRequireOfferValidationInTransfer(false)
await gammaCards.transferCard(address1.address, getCardsByUserResult[0][0])
Expand All @@ -159,16 +159,16 @@ describe('NoF - Gamma Cards Tests', function () {

const cardNumber = getCardsByUserResult1[0][0]
let quantity = await gammaCards.getCardQuantityByUser(address0.address, cardNumber)
await expect(quantity).to.be.equal(2)
expect(quantity).to.be.equal(2)

await gammaOffers.createOffer(uuidv4(), cardNumber, [1, 2, 24, 4, 5, 6, 7, 8])
let offers = await gammaOffers.getOffers()
await expect(offers.length).to.not.be.equal(0)
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)
expect(quantity).to.be.equal(1)
})

it('Should allow to transfer several cards', async () => {
Expand All @@ -184,9 +184,9 @@ describe('NoF - Gamma Cards Tests', function () {
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)
expect(quantity1).to.be.equal(0)
expect(quantity2).to.be.equal(0)
expect(quantity3).to.be.equal(0)
})

it('Should allow to finish album', async () => {
Expand Down Expand Up @@ -320,4 +320,72 @@ describe('NoF - Gamma Cards Tests', function () {
expect(userFinalTokenBalance > userInitialTokenBalance).to.be.true
expect(userTickets.length).greaterThan(0)
})

it('Should allow to burn card with offer and more than 2 copies', async () => {
const { testDAI, gammaPacks, gammaCards, gammaOffers, gammaTickets, address0 } =
await loadFixture(deployNofGammaFixture)

const amount = ethers.BigNumber.from('120000000000000000000') // 120 DAIs
await testDAI.approve(gammaPacks.address, amount)
await testDAI.approve(gammaCards.address, amount)

await gammaPacks.buyPacks(10) // buy packs to increase prizesBalance in gamma cards;

await gammaCards.testAddCards(address0.address) // 1 copy of each card
await gammaCards.testAddCards(address0.address) // 2 copies of each card
await gammaCards.testAddCards(address0.address) // 3 copies of each card

const userCopiesCard1 = await gammaCards.getCardQuantityByUser(address0.address, 1);
expect(userCopiesCard1).to.be.equal(3)

const userInitialTokenBalance = await testDAI.balanceOf(address0.address)

const cardsToBurn = []
for (let i = 1; i <= 60; i++) {
cardsToBurn.push(i);
}

await gammaOffers.createOffer(uuidv4(), 1, [2, 24])
let offers = await gammaOffers.getOffers()
expect(offers.length).to.not.be.equal(0)

await gammaCards.burnCards(cardsToBurn)
const userFinalTokenBalance = await testDAI.balanceOf(address0.address)
const userTickets = await gammaTickets.getTicketsByUser(address0.address)

expect(await gammaCards.hasCard(address0.address, 1)).to.be.true
expect(userFinalTokenBalance > userInitialTokenBalance).to.be.true
expect(userTickets.length).greaterThan(0)
})

it('Should revert when try to burn 2 copies of one card with offer and only 3 copies', async () => {
const { testDAI, gammaPacks, gammaCards, gammaOffers, address0 } =
await loadFixture(deployNofGammaFixture)

const amount = ethers.BigNumber.from('120000000000000000000') // 120 DAIs
await testDAI.approve(gammaPacks.address, amount)
await testDAI.approve(gammaCards.address, amount)

await gammaPacks.buyPacks(10) // buy packs to increase prizesBalance in gamma cards;

await gammaCards.testAddCards(address0.address) // 1 copy of each card
await gammaCards.testAddCards(address0.address) // 2 copies of each card
await gammaCards.testAddCards(address0.address) // 3 copies of each card

const userCopiesCard1 = await gammaCards.getCardQuantityByUser(address0.address, 1);
expect(userCopiesCard1).to.be.equal(3)

const cardsToBurn = [1, 1] // 2 copies of card 1
for (let i = 3; i <= 60; i++) {
cardsToBurn.push(i);
}

await gammaOffers.createOffer(uuidv4(), 1, [2, 24])
let offers = await gammaOffers.getOffers()
expect(offers.length).to.not.be.equal(0)

expect(await gammaCards.burnCards(cardsToBurn)).to.be.revertedWith('You cannot burn any more copies of this card.')
})


})

0 comments on commit ed03e47

Please sign in to comment.