From a5047df59202b3aa99d3866f1fc78cb5c1ce7411 Mon Sep 17 00:00:00 2001 From: Lulox Date: Sat, 14 Dec 2024 14:23:41 -0300 Subject: [PATCH] Fixed linting bug? Added USDC to contracts and frontend, still needs approval on frontend and likes integration on contracts --- packages/foundry/contracts/MockUSDC.sol | 6 +- packages/foundry/contracts/PunkSociety.sol | 11 +- packages/foundry/contracts/SimpleFaucet.sol | 22 +- packages/foundry/foundry.toml | 4 +- packages/foundry/script/Deploy.s.sol | 16 +- packages/nextjs/app/explore/Explore.tsx | 78 +- .../nextjs/app/profile/[address]/page.tsx | 3 +- packages/nextjs/components/Header.tsx | 40 +- .../nextjs/contracts/deployedContracts.ts | 2513 +++++++++++++++++ packages/nextjs/scaffold.config.ts | 4 +- 10 files changed, 2635 insertions(+), 62 deletions(-) diff --git a/packages/foundry/contracts/MockUSDC.sol b/packages/foundry/contracts/MockUSDC.sol index 7d9d721..f452f19 100644 --- a/packages/foundry/contracts/MockUSDC.sol +++ b/packages/foundry/contracts/MockUSDC.sol @@ -6,8 +6,10 @@ import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import { ERC20Permit } from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; -contract USDC is ERC20, ERC20Permit { - constructor() ERC20("USDC", "USDC") ERC20Permit("USDC") { } +contract MockUSDC is ERC20, ERC20Permit { + constructor() ERC20("USDC", "USDC") ERC20Permit("USDC") { + _mint(msg.sender, 100000 * 1e18); + } function decimals() public view virtual override returns (uint8) { return 6; diff --git a/packages/foundry/contracts/PunkSociety.sol b/packages/foundry/contracts/PunkSociety.sol index 860c942..91cb804 100644 --- a/packages/foundry/contracts/PunkSociety.sol +++ b/packages/foundry/contracts/PunkSociety.sol @@ -5,6 +5,8 @@ import { PunkProfile } from "./PunkProfile.sol"; import { PunkPosts } from "./PunkPosts.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; + +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; // import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; // import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; @@ -65,6 +67,7 @@ contract PunkSociety is Ownable { uint256 public postIds; PunkProfile public punkProfile; PunkPosts public punkPosts; + IERC20 public mockUSDC; mapping(uint256 => address) public postIdToUser; mapping(address => uint256[]) public userPosts; @@ -94,9 +97,14 @@ contract PunkSociety is Ownable { CONSTRUCTOR FUNCTION //////////////////////////////////////////////////////////////*/ - constructor(address _punkProfile, address _punkPosts) Ownable(msg.sender) { + constructor( + address _punkProfile, + address _punkPosts, + address _mockUSDC + ) Ownable(msg.sender) { punkProfile = PunkProfile(_punkProfile); punkPosts = PunkPosts(_punkPosts); + mockUSDC = IERC20(_mockUSDC); } /*////////////////////////////////////////////////////////////// @@ -111,6 +119,7 @@ contract PunkSociety is Ownable { postIdToUser[postId] = msg.sender; userPosts[msg.sender].push(postId); + mockUSDC.transferFrom(msg.sender, owner(), 3 * 1e6); punkPosts.mint(_tokenURI); // payable(owner()).transfer(3 ether); diff --git a/packages/foundry/contracts/SimpleFaucet.sol b/packages/foundry/contracts/SimpleFaucet.sol index 965b5f2..f34ba64 100644 --- a/packages/foundry/contracts/SimpleFaucet.sol +++ b/packages/foundry/contracts/SimpleFaucet.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + error FailedToTransfer(); contract SimpleFaucet { @@ -8,8 +10,15 @@ contract SimpleFaucet { mapping(address => bool) public hasClaimed; // Ether to be dispensed (10 USDC in 18 decimals) - // uint256 public constant AMOUNT = 10 ether; - uint256 public constant AMOUNT = 0.01 ether; + uint256 public constant AMOUNT = 10 * 1e6; + // uint256 public constant AMOUNT = 0.01 ether; + IERC20 public mockUSDC; + + constructor( + address _mockUSDC + ) { + mockUSDC = IERC20(_mockUSDC); + } // Only allow each address to claim once modifier onlyOnce() { @@ -19,13 +28,16 @@ contract SimpleFaucet { // Function to claim ETH function claim() external onlyOnce { - require(address(this).balance >= AMOUNT, "Insufficient faucet balance"); + require( + mockUSDC.balanceOf(address(this)) >= AMOUNT, "Insufficient faucet balance" + ); // Mark address as having claimed hasClaimed[msg.sender] = true; - // Transfer 10 ETH to the claimant - payable(msg.sender).transfer(AMOUNT); + // Transfer 10 USDC to the claimant + // payable(msg.sender).transfer(AMOUNT); + mockUSDC.transfer(msg.sender, AMOUNT); } // Function to deposit ETH into the faucet diff --git a/packages/foundry/foundry.toml b/packages/foundry/foundry.toml index 860caff..357b72a 100644 --- a/packages/foundry/foundry.toml +++ b/packages/foundry/foundry.toml @@ -5,8 +5,8 @@ libs = ['lib'] fs_permissions = [{ access = "read-write", path = "./"}] [rpc_endpoints] -default_network = "${PUNKSOCIETY_RPC_URL}" -localhost = "${PUNKSOCIETY_RPC_URL}" +default_network = "http://127.0.0.1:8545" +localhost = "http://127.0.0.1:8545" punksociety = "${PUNKSOCIETY_RPC_URL}" avalancheFuji = "https://api.avax-test.network/ext/bc/C/rpc" diff --git a/packages/foundry/script/Deploy.s.sol b/packages/foundry/script/Deploy.s.sol index 79087dd..01230e0 100644 --- a/packages/foundry/script/Deploy.s.sol +++ b/packages/foundry/script/Deploy.s.sol @@ -5,6 +5,7 @@ import { PunkPosts } from "../contracts/PunkPosts.sol"; import { PunkProfile } from "../contracts/PunkProfile.sol"; import { PunkSociety } from "../contracts/PunkSociety.sol"; import { SimpleFaucet } from "../contracts/SimpleFaucet.sol"; +import { MockUSDC } from "../contracts/MockUSDC.sol"; import "./DeployHelpers.s.sol"; contract DeployScript is ScaffoldETHDeploy { @@ -14,6 +15,7 @@ contract DeployScript is ScaffoldETHDeploy { PunkProfile punkProfile; PunkSociety punkSociety; + MockUSDC mockUSDC; SimpleFaucet simpleFaucet; error InvalidPrivateKey(string); @@ -27,7 +29,11 @@ contract DeployScript is ScaffoldETHDeploy { } vm.startBroadcast(deployerPrivateKey); - // Deploying just to get the ABI from the frontend + mockUSDC = new MockUSDC(); + console.logString( + string.concat("MockUSDC deployed at: ", vm.toString(address(mockUSDC))) + ); + punkPosts = new PunkPosts(); console.logString( string.concat("PunkPosts deployed at: ", vm.toString(address(punkPosts))) @@ -40,7 +46,9 @@ contract DeployScript is ScaffoldETHDeploy { ) ); - punkSociety = new PunkSociety(address(punkProfile), address(punkPosts)); + punkSociety = new PunkSociety( + address(punkProfile), address(punkPosts), address(mockUSDC) + ); console.logString( string.concat( "PunkSociety deployed at: ", vm.toString(address(punkSociety)) @@ -55,13 +63,15 @@ contract DeployScript is ScaffoldETHDeploy { ) ); - simpleFaucet = new SimpleFaucet(); + simpleFaucet = new SimpleFaucet(address(mockUSDC)); console.logString( string.concat( "SimpleFaucet deployed at: ", vm.toString(address(simpleFaucet)) ) ); + mockUSDC.transfer(address(simpleFaucet), 50000 * 1e18); + // Transfer 5000 USDC to the simpleFaucet // payable(address(simpleFaucet)).transfer(5000 * 1e18); // payable(address(simpleFaucet)).transfer(0.5 * 1e18); diff --git a/packages/nextjs/app/explore/Explore.tsx b/packages/nextjs/app/explore/Explore.tsx index f25d3f8..e1cc8ae 100644 --- a/packages/nextjs/app/explore/Explore.tsx +++ b/packages/nextjs/app/explore/Explore.tsx @@ -1,12 +1,11 @@ "use client"; import { useCallback, useEffect, useRef, useState } from "react"; -// import Image from "next/image"; +import Image from "next/image"; import { LoadingBars } from "../../components/punk-society/LoadingBars"; import { NewsFeed } from "../../components/punk-society/NewsFeed"; -// import { useAccount } from "wagmi"; -import { useScaffoldEventHistory } from "~~/hooks/scaffold-eth"; -// import { useScaffoldEventHistory, useScaffoldReadContract, useScaffoldWriteContract } from "~~/hooks/scaffold-eth"; +import { useAccount } from "wagmi"; +import { useScaffoldEventHistory, useScaffoldReadContract, useScaffoldWriteContract } from "~~/hooks/scaffold-eth"; import { notification } from "~~/utils/scaffold-eth"; import { getMetadataFromIPFS } from "~~/utils/simpleNFT/ipfs-fetch"; import { NFTMetaData } from "~~/utils/simpleNFT/nftsMetadata"; @@ -25,8 +24,8 @@ export const Explore = () => { const [page, setPage] = useState(0); const [activeTab, setActiveTab] = useState("Global"); - // const { address: connectedAddress } = useAccount(); - // const { writeContractAsync } = useScaffoldWriteContract("SimpleFaucet"); + const { address: connectedAddress } = useAccount(); + const { writeContractAsync } = useScaffoldWriteContract("SimpleFaucet"); const handleTabClick = (tab: any) => { setActiveTab(tab); @@ -34,36 +33,36 @@ export const Explore = () => { const observer = useRef(null); - // const { data: isClaimed } = useScaffoldReadContract({ - // contractName: "SimpleFaucet", - // functionName: "hasClaimed", - // args: [connectedAddress], - // watch: true, - // }); - - // const handleClaimUSDC = async () => { - // if (!connectedAddress) { - // notification.error("Please connect your wallet"); - // return; - // } - - // setLoading(true); - - // try { - // const contractResponse = await writeContractAsync({ - // functionName: "claim", - // // args: [], - // }); - - // if (contractResponse) { - // notification.success("Claimed 10 USDC successfully!"); - // } - // } catch (error) { - // console.error("Error during claiming USDC:", error); - // notification.error("Claiming USDC failed, please try again."); - // } finally { - // } - // }; + const { data: isClaimed } = useScaffoldReadContract({ + contractName: "SimpleFaucet", + functionName: "hasClaimed", + args: [connectedAddress], + watch: true, + }); + + const handleClaimUSDC = async () => { + if (!connectedAddress) { + notification.error("Please connect your wallet"); + return; + } + + setLoading(true); + + try { + const contractResponse = await writeContractAsync({ + functionName: "claim", + // args: [], + }); + + if (contractResponse) { + notification.success("Claimed 10 USDC successfully!"); + } + } catch (error) { + console.error("Error during claiming USDC:", error); + notification.error("Claiming USDC failed, please try again."); + } finally { + } + }; const { data: createEvents, @@ -72,7 +71,8 @@ export const Explore = () => { } = useScaffoldEventHistory({ contractName: "PunkSociety", eventName: "PostCreated", - fromBlock: 18350669n, + // fromBlock: 18350669n, + fromBlock: 0n, watch: true, }); @@ -150,7 +150,7 @@ export const Explore = () => { return (
- {/* {!isClaimed && ( + {!isClaimed && ( - )} */} + )}