Skip to content

Commit

Permalink
add furry fox friends
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffreyscholz committed Apr 27, 2023
1 parent 0a5717d commit 9e54c73
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
67 changes: 67 additions & 0 deletions contracts/FurryFoxFriends.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable2Step.sol";

/*
$$$$$$$$\ $$$$$$$$\
$$ _____| $$ _____|
$$ | $$\ $$\ $$$$$$\ $$$$$$\ $$\ $$\ $$ | $$$$$$\ $$\ $$\
$$$$$\ $$ | $$ |$$ __$$\ $$ __$$\ $$ | $$ | $$$$$\ $$ __$$\ \$$\ $$ |
$$ __|$$ | $$ |$$ | \__|$$ | \__|$$ | $$ | $$ __|$$ / $$ | \$$$$ /
$$ | $$ | $$ |$$ | $$ | $$ | $$ | $$ | $$ | $$ | $$ $$<
$$ | \$$$$$$ |$$ | $$ | \$$$$$$$ | $$ | \$$$$$$ |$$ /\$$\
\__| \______/ \__| \__| \____$$ | \__| \______/ \__/ \__|
$$\ $$ |
\$$$$$$ |
\______/
$$$$$$$$\ $$\ $$\ $$\ $$\ $$$$$$$$\ $$$$$$$$\
$$ _____| \__| $$ | $$$\ $$ |$$ _____|\__$$ __|
$$ | $$$$$$\ $$\ $$$$$$\ $$$$$$$\ $$$$$$$ | $$$$$$$\ $$$$\ $$ |$$ | $$ |
$$$$$\ $$ __$$\ $$ |$$ __$$\ $$ __$$\ $$ __$$ |$$ _____| $$ $$\$$ |$$$$$\ $$ |
$$ __|$$ | \__|$$ |$$$$$$$$ |$$ | $$ |$$ / $$ |\$$$$$$\ $$ \$$$$ |$$ __| $$ |
$$ | $$ | $$ |$$ ____|$$ | $$ |$$ | $$ | \____$$\ $$ |\$$$ |$$ | $$ |
$$ | $$ | $$ |\$$$$$$$\ $$ | $$ |\$$$$$$$ |$$$$$$$ | $$ | \$$ |$$ | $$ |
\__| \__| \__| \_______|\__| \__| \_______|\_______/ \__| \__|\__| \__|
*/

// You didn't get on the presale for the FurryFoxFriends NFTs?
// No worries, you can still get one!
contract FurryFoxFriends is ERC721("FurryFoxFriends", "F3"), Ownable2Step {
using MerkleProof for bytes32;

bytes32 merkleRoot;
uint256 totalSupply;
bool isPublicSale;
mapping(address => bool) alreadyMinted;
mapping(bytes32 => bool) alreadyUsedLeaf;

function openPresale() external onlyOwner {
isPublicSale = true;
}

function setNewMerkleRoot(bytes32 newMerkleRoot) external onlyOwner {
merkleRoot = newMerkleRoot;
}

function presaleMint(bytes32[] calldata proof, bytes32 leaf) external {
require(MerkleProof.verifyCalldata(proof, merkleRoot, leaf), "not verified");
require(!alreadyMinted[msg.sender], "already minted");
require(!alreadyUsedLeaf[leaf], "leaf already used");

totalSupply++;
_mint(msg.sender, totalSupply - 1);
}

function mint() external {
require(isPublicSale, "public sale not open");

totalSupply++;
_mint(msg.sender, totalSupply - 1);
}
}
35 changes: 35 additions & 0 deletions test/FurryFoxFriends.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers");
const { expect } = require("chai");
const { ethers } = require("hardhat");

const NAME = "FurryFoxFriends Test";

describe(NAME, function () {
async function setup() {
const [, attackerWallet] = await ethers.getSigners();
const value = ethers.utils.parseEther("1");

const nftFactory = await ethers.getContractFactory("FurryFoxFriends");
const nftContract = await nftFactory.deploy();

return { nftContract, attackerWallet };
}

describe("exploit", async function () {
let nftContract, attackerWallet;
before(async function () {
({ walletContract, nftContract, attackerWallet } = await loadFixture(setup));
const attackerBalance = await nftContract.balanceOf(attackerWallet.address);
expect(attackerBalance).to.be.equal(0, "attacker starts with no NFT");
});

it("conduct your attack here", async function () {
// do it
});

after(async function () {
const attackerBalance = await nftContract.balanceOf(attackerWallet.address);
expect(attackerBalance).to.be.greaterThanOrEqual(1, "attacker must acquire an NFT");
});
});
});

0 comments on commit 9e54c73

Please sign in to comment.