Skip to content
This repository has been archived by the owner on Jan 6, 2025. It is now read-only.

Brian doyle/add mentor nft #2

Merged
merged 3 commits into from
May 3, 2024
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
118 changes: 118 additions & 0 deletions contracts/HackathonMinter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

import "hardhat/console.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Base64.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

// Airdrop the NFT to the supplied address
// Only allowlisted addresses can mint

contract HackathonMinter is ERC721, Ownable {
using EnumerableSet for EnumerableSet.AddressSet;

EnumerableSet.AddressSet private allowed;

uint public counter;
string public nameString;
string public description;
string public tokenArtIPFSId;

mapping(address => bool) public minted;

error InvalidTokenId(uint tokenId);
error OneMintPerAddress();
error NotAllowed();
error SoulboundToken();

constructor(
string memory _nameString,
string memory _symbol,
string memory _tokenArtIPFSId,
string memory _description
) ERC721(_nameString, _symbol) Ownable(msg.sender) {
nameString = _nameString;
description = _description;
tokenArtIPFSId = _tokenArtIPFSId;

allowed.add(msg.sender);
}

function mintFor(address _recipient) public allowedOnly {
if (minted[_recipient]) {
revert OneMintPerAddress();
}
minted[_recipient] = true;
counter++;
_safeMint(_recipient, counter);
}

function _baseURI() internal pure override returns (string memory) {
return "data:application/json;base64,";
}

function tokenURI(
uint _tokenId
) public view override returns (string memory) {
if (_tokenId > counter) {
revert InvalidTokenId(_tokenId);
}

string memory json = Base64.encode(
bytes(
string(
abi.encodePacked(
'{"name": "',
nameString,
" #: ",
Strings.toString(_tokenId),
'","description": "',
'", "image": "ipfs://',
tokenArtIPFSId,
'"}'
)
)
)
);

return string(abi.encodePacked(_baseURI(), json));
}

/**
* Disallow transfers (Soulbound NFT)
*/
/**
* @dev Internal function to handle token transfers.
* Restricts the transfer of Soulbound tokens.
*/
function _update(
address to,
uint256 tokenId,
address auth
) internal override(ERC721) returns (address) {
address from = _ownerOf(tokenId);
if (from != address(0) && to != address(0)) {
revert SoulboundToken();
}

return super._update(to, tokenId, auth);
}

function addAllowed(address _address) public allowedOnly {
allowed.add(_address);
}

function removeAllowed(address _address) public allowedOnly {
allowed.remove(_address);
}

modifier allowedOnly() {
if (!allowed.contains(msg.sender)) {
revert NotAllowed();
}
_;
}
}
47 changes: 47 additions & 0 deletions deploy/011_deploy_farcon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { ethers } from "hardhat";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts } = hre;
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();

const argumentValues = [
"Base @ FarHack 2024", // Name
"BFC24", // Symbol
"QmQmgBTcXSrAVd1yuhuyN5hk8PfzfKihneG6nj5sKN6svk", // IPFS Hash
"Base @ FarHack 2024", // Description
];

const DeployedContract = await deploy("BaseAtFarHack", {
from: deployer,
contract: "HackathonMinter",
args: argumentValues,
});

const deployedContract = await ethers.getContractAt(
"HackathonMinter",
DeployedContract.address
);

await deployedContract.addAllowed(
"0x95e32ba428421a24d77ddcc882696330161963b2"
); // Taylor
await deployedContract.addAllowed(
"0x01658f5d899e03492dC832C8eE8839FFD80b7f09"
); // Carl
await deployedContract.addAllowed(
"0x836fa72d2af55d698e8767acbe88c042b8201036"
); // Ryan
await deployedContract.addAllowed(
"0x058F4718624fCC5006d89ecC8c76E5bAf5320590"
); // Ryan Alt

await hre.run("verify:verify", {
address: DeployedContract.address,
constructorArguments: argumentValues,
contract: "contracts/HackathonMinter.sol:HackathonMinter",
});
};
export default func;
28 changes: 28 additions & 0 deletions deployed/007_deploy_base_bootcamp_mentor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts } = hre;
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();

const argumentValues = [
"Base Bootcamp Mentor", // Name
"BBM", // Symbol
"QmWQh28UdFUyKd7fRPbTN8ieeVfW7Dz9Qn6XdExP3DnUzU", // IPFS Hash
"Thank you for serving as a mentor for Base Bootcamp!", // Description
];

const DeployedContract = await deploy("BaseBootcampMentor", {
from: deployer,
contract: "HackathonMinter",
args: argumentValues,
});

await hre.run("verify:verify", {
address: DeployedContract.address,
constructorArguments: argumentValues,
contract: "contracts/HackathonMinter.sol:HackathonMinter",
});
};
export default func;
45 changes: 45 additions & 0 deletions deployed/008_deploy_paris_frames_hackathon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { ethers } from "hardhat";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts } = hre;
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();

const argumentValues = [
"Paris Base Frames Hackathon 2024", // Name
"PBFJ24", // Symbol
"QmWbTKaz94dWEqPKKpTgCoSuuzzXSnmj3S8rM23wLLZXc1", // IPFS Hash
"Paris Base Frames Hackathon 2024", // Description
];

const DeployedContract = await deploy("ParisBaseFrames24", {
from: deployer,
contract: "HackathonMinter",
args: argumentValues,
});

const deployedContract = await ethers.getContractAt(
"HackathonMinter",
DeployedContract.address
);

await deployedContract.addAllowed(
"0x95e32ba428421a24d77ddcc882696330161963b2"
); // Taylor
await deployedContract.addAllowed(
"0x01658f5d899e03492dC832C8eE8839FFD80b7f09"
); // Carl
await deployedContract.addAllowed(
"0x836fa72d2af55d698e8767acbe88c042b8201036"
); // Ryan


await hre.run("verify:verify", {
address: DeployedContract.address,
constructorArguments: argumentValues,
contract: "contracts/HackathonMinter.sol:HackathonMinter",
});
};
export default func;
38 changes: 38 additions & 0 deletions deployed/009_deploy_singapore_frames_hackathon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { ethers } from "hardhat";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts } = hre;
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();

const argumentValues = [
"Singapore Base Frames Hackathon 2024", // Name
"SBFJ24", // Symbol
"QmbyUzL8DW37TDoU6K3eNPSLxdqYzk15R9TpWDgYvuqwWk", // IPFS Hash
"Singapore Base Frames Hackathon 2024", // Description
];

const DeployedContract = await deploy("SingaporeBaseFrames24", {
from: deployer,
contract: "HackathonMinter",
args: argumentValues,
});

const deployedContract = await ethers.getContractAt(
"HackathonMinter",
DeployedContract.address
);

await deployedContract.addAllowed(
"0x4d120d7d8019c7616d4e14249fb696c6a5fe0b6b"
); // Qi Wu

await hre.run("verify:verify", {
address: DeployedContract.address,
constructorArguments: argumentValues,
contract: "contracts/HackathonMinter.sol:HackathonMinter",
});
};
export default func;
47 changes: 47 additions & 0 deletions deployed/010_deploy_eth_dubai_24.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { ethers } from "hardhat";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployments, getNamedAccounts } = hre;
const { deploy } = deployments;
const { deployer } = await getNamedAccounts();

const argumentValues = [
"Base Hackathon ETHDubai 2024", // Name
"BHED24", // Symbol
"QmfSsY6qnyjxy8zpzUaFPdRxAmndWtyRr6rV3KAv3YsSi3", // IPFS Hash
"Base Hackathon ETHDubai 2024", // Description
];

const DeployedContract = await deploy("ETHDubai24", {
from: deployer,
contract: "HackathonMinter",
args: argumentValues,
});

const deployedContract = await ethers.getContractAt(
"HackathonMinter",
DeployedContract.address
);

await deployedContract.addAllowed(
"0x95e32ba428421a24d77ddcc882696330161963b2"
); // Taylor
await deployedContract.addAllowed(
"0x01658f5d899e03492dC832C8eE8839FFD80b7f09"
); // Carl
await deployedContract.addAllowed(
"0x836fa72d2af55d698e8767acbe88c042b8201036"
); // Ryan
await deployedContract.addAllowed(
"0x058F4718624fCC5006d89ecC8c76E5bAf5320590"
); // Ryan Alt

await hre.run("verify:verify", {
address: DeployedContract.address,
constructorArguments: argumentValues,
contract: "contracts/HackathonMinter.sol:HackathonMinter",
});
};
export default func;
Loading
Loading