Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 🦺 check if user has enough copies to burn with off… #116

Merged
merged 1 commit into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.')
})


})