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

Commit

Permalink
Merge pull request #2 from base-org/brian-doyle/add-mentor-nft
Browse files Browse the repository at this point in the history
Brian doyle/add mentor nft
  • Loading branch information
briandoyle81CB authored May 3, 2024
2 parents 7da735c + 993daed commit 1f1baaf
Show file tree
Hide file tree
Showing 13 changed files with 5,784 additions and 0 deletions.
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;
File renamed without changes.
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

0 comments on commit 1f1baaf

Please sign in to comment.