This repository has been archived by the owner on Jan 6, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from base-org/brian-doyle/add-mentor-nft
Brian doyle/add mentor nft
- Loading branch information
Showing
13 changed files
with
5,784 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
_; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Oops, something went wrong.