Skip to content

Commit

Permalink
update the reviews
Browse files Browse the repository at this point in the history
  • Loading branch information
Superior212 committed Oct 16, 2024
1 parent 8686d19 commit 61d78fd
Show file tree
Hide file tree
Showing 11 changed files with 20,844 additions and 2,994 deletions.
18,317 changes: 18,317 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/hardhat/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
# To access the values stored in this .env file you can use: process.env.VARIABLENAME
ALCHEMY_API_KEY=
DEPLOYER_PRIVATE_KEY=
ETHERSCAN_API_KEY=
ETHERSCAN_API_KEY=
178 changes: 95 additions & 83 deletions packages/hardhat/contracts/BatchRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,87 +5,99 @@ import "@openzeppelin/contracts/access/Ownable.sol";
import "./BatchGraduationNFT.sol";

contract BatchRegistry is Ownable {
uint16 public immutable BATCH_NUMBER;
uint256 constant CHECK_IN_REWARD = 0.01 ether;
BatchGraduationNFT public batchGraduationNFT;

mapping(address => bool) public allowList;
mapping(address => address) public yourContractAddress;
mapping(address => uint256) public graduatedTokenId;
bool public isOpen = true;
bool public graduationOpen = false;
uint256 public checkedInCounter;

event CheckedIn(bool first, address builder, address checkInContract);

// Errors
error BatchNotOpen();
error NotAContract();
error NotInAllowList();
error AlreadyGraduated();
error NotCheckedIn();
error GraduationClosed();

modifier batchIsOpen() {
if (!isOpen) revert BatchNotOpen();
_;
}

modifier senderIsContract() {
if (tx.origin == msg.sender) revert NotAContract();
_;
}

constructor(address initialOwner, uint16 batchNumber) Ownable(initialOwner) {
batchGraduationNFT = new BatchGraduationNFT(address(this));
BATCH_NUMBER = batchNumber;
}

function updateAllowList(address[] calldata builders, bool[] calldata statuses) public onlyOwner {
require(builders.length == statuses.length, "Builders and statuses length mismatch");

for (uint256 i = 0; i < builders.length; i++) {
allowList[builders[i]] = statuses[i];
}
}

function toggleBatchOpenStatus() public onlyOwner {
isOpen = !isOpen;
}

function toggleGraduationOpenStatus() public onlyOwner {
graduationOpen = !graduationOpen;
}

function checkIn() public senderIsContract batchIsOpen {
if (!allowList[tx.origin]) revert NotInAllowList();

bool wasFirstTime;
if (yourContractAddress[tx.origin] == address(0)) {
checkedInCounter++;
wasFirstTime = true;
(bool success,) = tx.origin.call{value: CHECK_IN_REWARD}("");
require(success, "Failed to send check in reward");
}

yourContractAddress[tx.origin] = msg.sender;
emit CheckedIn(wasFirstTime, tx.origin, msg.sender);
}

function graduate() public {
if (!graduationOpen) revert GraduationClosed();
if (graduatedTokenId[msg.sender] != 0) revert AlreadyGraduated();
if (yourContractAddress[msg.sender] == address(0)) revert NotCheckedIn();

uint256 newTokenId = batchGraduationNFT.mint(msg.sender);
graduatedTokenId[msg.sender] = newTokenId;
}

// Withdraw function for admins in case some builders don't end up checking in
function withdraw() public onlyOwner {
(bool success,) = payable(owner()).call{value: address(this).balance}("");
require(success, "Failed to withdraw");
}

receive() external payable {}
uint16 public immutable BATCH_NUMBER;
uint256 constant CHECK_IN_REWARD = 0.01 ether;
BatchGraduationNFT public batchGraduationNFT;

mapping(address => bool) public allowList;
mapping(address => address) public yourContractAddress;
mapping(address => uint256) public graduatedTokenId;
bool public isOpen = true;
bool public graduationOpen = false;
uint256 public checkedInCounter;

event CheckedIn(bool first, address builder, address checkInContract);

// Errors
error BatchNotOpen();
error NotAContract();
error NotInAllowList();
error AlreadyGraduated();
error NotCheckedIn();
error GraduationClosed();

modifier batchIsOpen() {
if (!isOpen) revert BatchNotOpen();
_;
}

modifier senderIsContract() {
if (tx.origin == msg.sender) revert NotAContract();
_;
}

constructor(
address initialOwner,
uint16 batchNumber
) Ownable(initialOwner) {
batchGraduationNFT = new BatchGraduationNFT(address(this));
BATCH_NUMBER = batchNumber;
}

function updateAllowList(
address[] calldata builders,
bool[] calldata statuses
) public onlyOwner {
require(
builders.length == statuses.length,
"Builders and statuses length mismatch"
);

for (uint256 i = 0; i < builders.length; i++) {
allowList[builders[i]] = statuses[i];
}
}

function toggleBatchOpenStatus() public onlyOwner {
isOpen = !isOpen;
}

function toggleGraduationOpenStatus() public onlyOwner {
graduationOpen = !graduationOpen;
}

function checkIn() public senderIsContract batchIsOpen {
if (!allowList[tx.origin]) revert NotInAllowList();

bool wasFirstTime;
if (yourContractAddress[tx.origin] == address(0)) {
checkedInCounter++;
wasFirstTime = true;
(bool success, ) = tx.origin.call{ value: CHECK_IN_REWARD }("");
require(success, "Failed to send check in reward");
}

yourContractAddress[tx.origin] = msg.sender;
emit CheckedIn(wasFirstTime, tx.origin, msg.sender);
}

function graduate() public {
if (!graduationOpen) revert GraduationClosed();
if (graduatedTokenId[msg.sender] != 0) revert AlreadyGraduated();
if (yourContractAddress[msg.sender] == address(0))
revert NotCheckedIn();

uint256 newTokenId = batchGraduationNFT.mint(msg.sender);
graduatedTokenId[msg.sender] = newTokenId;
}

// Withdraw function for admins in case some builders don't end up checking in
function withdraw() public onlyOwner {
(bool success, ) = payable(owner()).call{
value: address(this).balance
}("");
require(success, "Failed to withdraw");
}

receive() external payable {}
}
30 changes: 0 additions & 30 deletions packages/hardhat/contracts/CheckIn.sol

This file was deleted.

13 changes: 2 additions & 11 deletions packages/hardhat/deploy/00_deploy_your_contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,19 @@ const deployYourContract: DeployFunction = async function (hre: HardhatRuntimeEn
await deploy("BatchRegistry", {
from: deployer,
// Contract constructor arguments
args: ["0x62CeF3Ca8b52a9C69a17236CA2c56Cdb7a383E8e", BATCH_NUMBER],
args: [deployer, BATCH_NUMBER],
log: true,
// autoMine: can be passed to the deploy function to make the deployment process faster on local networks by
// automatically mining the contract deployment transaction. There is no effect on live networks.
autoMine: true,
});

await deploy("CheckIn", {
from: deployer,
// Contract constructor arguments
args: ["0x0e51b39aa58887b43c14E9C831E77eE52BA38A29"],
log: true,
// autoMine: can be passed to the deploy function to make the deployment process faster on local networks by
// automatically mining the contract deployment transaction. There is no effect on live networks.
autoMine: true,
});
// Get the deployed contract to interact with it after deploying.
const batchRegistry = await hre.ethers.getContract<Contract>("BatchRegistry", deployer);
console.log("\nBatchRegistry deployed to:", await batchRegistry.getAddress());
console.log("Remember to update the allow list!\n");

// // The GraduationNFT contract is deployed on the BatchRegistry constructor.
// The GraduationNFT contract is deployed on the BatchRegistry constructor.
const batchGraduationNFTAddress = await batchRegistry.batchGraduationNFT();
console.log("BatchGraduation NFT deployed to:", batchGraduationNFTAddress, "\n");
};
Expand Down
12 changes: 1 addition & 11 deletions packages/hardhat/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,14 @@ import "solidity-coverage";
import "@nomicfoundation/hardhat-verify";
import "hardhat-deploy";
import "hardhat-deploy-ethers";
import { ethers } from "ethers";

// If not set, it uses ours Alchemy's default API key.
// You can get your own at https://dashboard.alchemyapi.io
const providerApiKey = process.env.ALCHEMY_API_KEY || "oKxs-03sij-U_N0iOlrSsZFr29-IqbuF";
// If not set, it uses the hardhat account 0 private key.

const deployerPrivateKey =
process.env.DEPLOYER_PRIVATE_KEY ?? "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
// If not set, it uses ours Etherscan default API key.

if (deployerPrivateKey && deployerPrivateKey.length > 6) {
console.log(`Using private key ending in ...${deployerPrivateKey.slice(-6)}`);
const wallet = new ethers.Wallet(deployerPrivateKey);
console.log(`Corresponding public address: ${wallet.address}`);
} else {
console.log("Private key is not set or invalid");
}
const etherscanApiKey = process.env.ETHERSCAN_API_KEY || "DNXJA8RX2Q3VZ4URQIWP7Z68CJXQZSC6AW";

const config: HardhatUserConfig = {
Expand All @@ -44,7 +34,7 @@ const config: HardhatUserConfig = {
},
],
},
defaultNetwork: "optimism",
defaultNetwork: "localhost",
namedAccounts: {
deployer: {
// By default, it will take the first Hardhat account as the deployer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
import Image from "next/image";
import { Github, Linkedin, Twitter } from "lucide-react";
import { NextPage } from "next";
import { FaGithub, FaLinkedin } from "react-icons/fa";
import { FaXTwitter } from "react-icons/fa6";

const BuilderProfile: NextPage = () => {
const socialLinks = [
{
href: "https://github.com/Superior212",
label: "Github",
icon: <FaGithub size={24} />,
},
{
href: "https://x.com/Samsonaderonmu",
label: "Twitter",
icon: <FaXTwitter size={24} />,
},
{
href: "https://www.linkedin.com/in/samsonaderonmu",
label: "LinkedIn",
icon: <FaLinkedin size={24} />,
},
];

export default function BuilderProfile() {
return (
<div className="flex flex-col items-center justify-center min-h-screen bg-gradient-to-br from-base-200 to-base-300">
<div className="card w-96 bg-base-100 shadow-xl">
Expand All @@ -19,33 +39,22 @@ export default function BuilderProfile() {
at a time.
</p>
<div className="card-actions justify-center mt-4">
<a
href="https://github.com/Superior212"
target="_blank"
rel="noopener noreferrer"
className="btn btn-ghost btn-square"
>
<Github className="h-6 w-6" />
</a>
<a
href="https://x.com/Samsonaderonmu"
target="_blank"
rel="noopener noreferrer"
className="btn btn-ghost btn-square"
>
<Twitter className="h-6 w-6" />
</a>
<a
href="https://www.linkedin.com/in/samsonaderonmu/e"
target="_blank"
rel="noopener noreferrer"
className="btn btn-ghost btn-square"
>
<Linkedin className="h-6 w-6" />
</a>
{socialLinks.map(link => (
<a
key={link.label}
href={link.href}
target="_blank"
rel="noopener noreferrer"
className="btn btn-ghost btn-square"
>
{link.icon}
</a>
))}
</div>
</div>
</div>
</div>
);
}
};

export default BuilderProfile;
Loading

0 comments on commit 61d78fd

Please sign in to comment.