feat: fill up challenge
Some checks failed
Lint / ci (lts/*, ubuntu-latest) (push) Has been cancelled

This commit is contained in:
han
2026-01-12 10:11:35 +07:00
parent 64378512ba
commit eca584fd05
10 changed files with 948 additions and 10 deletions

View File

@@ -10,18 +10,27 @@ contract CrowdFund {
/////////////////
// Errors go here...
error NotOpenToWithdraw();
error WithdrawTransferFailed(address to, uint256 amount);
error TooEarly(uint256 deadline, uint256 currentTimestamp);
error AlreadyCompleted();
//////////////////////
/// State Variables //
//////////////////////
FundingRecipient public fundingRecipient;
mapping(address => uint256) public balances;
bool public openToWithdraw;
uint256 public deadline = block.timestamp + 2 hours;
uint256 public constant threshold = 1 ether;
////////////////
/// Events /////
////////////////
// Events go here...
event Contribution(address, uint256);
///////////////////
/// Modifiers /////
@@ -29,6 +38,7 @@ contract CrowdFund {
modifier notCompleted() {
_;
if (block.timestamp >= deadline) revert AlreadyCompleted();
}
///////////////////
@@ -43,19 +53,42 @@ contract CrowdFund {
/// Functions /////
///////////////////
function contribute() public payable {}
function contribute() public payable {
balances[msg.sender] += msg.value;
emit Contribution(msg.sender, msg.value);
}
function withdraw() public {}
function withdraw() public {
if (!openToWithdraw) revert NotOpenToWithdraw();
function execute() public {}
uint256 amount = balances[msg.sender];
balances[msg.sender] = 0;
receive() external payable {}
(bool success,) = msg.sender.call{value: amount}("");
if (!success) revert WithdrawTransferFailed(msg.sender, amount);
}
function execute() public {
if (block.timestamp < deadline) revert TooEarly(deadline, block.timestamp);
uint256 balance = address(this).balance;
if (balance >= threshold) {
fundingRecipient.complete{value: balance}();
} else {
openToWithdraw = true;
}
}
receive() external payable {
contribute();
}
////////////////////////
/// View Functions /////
////////////////////////
function timeLeft() public view returns (uint256) {
return 0;
if (block.timestamp >= deadline) return 0;
return deadline - block.timestamp;
}
}

View File

@@ -0,0 +1 @@
11155111

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,76 @@
{
"address": "0xeA89D4E3dA2eb001631dD1c0CFa0D922869D1836",
"abi": [
{
"inputs": [],
"name": "complete",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "completed",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x7ad9d25092aed9d8f2ee38614dee5e9b457442ad32bf820384c0bc9aaf36c54c",
"receipt": {
"to": null,
"from": "0x2C24aE4fDc0d94FF458F9a12A4c2fF5E5E0a6ca6",
"contractAddress": "0xeA89D4E3dA2eb001631dD1c0CFa0D922869D1836",
"transactionIndex": 106,
"gasUsed": "87989",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"blockHash": "0xe9fa6a5e45cd6851195ebf9ba728928f4e5d2982f2d8606c64450ea2ae23b4b5",
"transactionHash": "0x7ad9d25092aed9d8f2ee38614dee5e9b457442ad32bf820384c0bc9aaf36c54c",
"logs": [],
"blockNumber": 10021914,
"cumulativeGasUsed": "20601449",
"status": 1,
"byzantium": true
},
"args": [],
"numDeployments": 1,
"solcInputHash": "458d1396e5cbe5b8f0626cefc89ad3a7",
"metadata": "{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"complete\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"completed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/FundingRecipient.sol\":\"FundingRecipient\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/FundingRecipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.20; // Do not change the solidity version as it negatively impacts submission grading\\n\\ncontract FundingRecipient {\\n bool public completed;\\n\\n function complete() public payable {\\n completed = true;\\n }\\n}\\n\",\"keccak256\":\"0x093e9f4390e6f225b75cb2775607526dbf062751fca91949ee80de147707f219\",\"license\":\"MIT\"}},\"version\":1}",
"bytecode": "0x6080604052348015600f57600080fd5b5060a08061001e6000396000f3fe60806040526004361060265760003560e01c8063522e117714602b5780639d9a7fe914603e575b600080fd5b603c6000805460ff19166001179055565b005b348015604957600080fd5b5060005460569060ff1681565b604051901515815260200160405180910390f3fea2646970667358221220db8e4d450c3ce702917ec87bbf961a466fe7b3581202297048bd7b39e9b649e064736f6c63430008140033",
"deployedBytecode": "0x60806040526004361060265760003560e01c8063522e117714602b5780639d9a7fe914603e575b600080fd5b603c6000805460ff19166001179055565b005b348015604957600080fd5b5060005460569060ff1681565b604051901515815260200160405180910390f3fea2646970667358221220db8e4d450c3ce702917ec87bbf961a466fe7b3581202297048bd7b39e9b649e064736f6c63430008140033",
"devdoc": {
"kind": "dev",
"methods": {},
"version": 1
},
"userdoc": {
"kind": "user",
"methods": {},
"version": 1
},
"storageLayout": {
"storage": [
{
"astId": 56,
"contract": "contracts/FundingRecipient.sol:FundingRecipient",
"label": "completed",
"offset": 0,
"slot": "0",
"type": "t_bool"
}
],
"types": {
"t_bool": {
"encoding": "inplace",
"label": "bool",
"numberOfBytes": "1"
}
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -37,7 +37,7 @@ const config: HardhatUserConfig = {
},
],
},
defaultNetwork: "localhost",
defaultNetwork: "sepolia", //"localhost",
namedAccounts: {
deployer: {
// By default, it will take the first Hardhat account as the deployer

View File

@@ -4,6 +4,441 @@
*/
import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract";
const deployedContracts = {} as const;
const deployedContracts = {
31337: {
CrowdFund: {
address: "0x09635F643e140090A9A8Dcd712eD6285858ceBef",
abi: [
{
inputs: [
{
internalType: "address",
name: "fundingRecipientAddress",
type: "address",
},
],
stateMutability: "nonpayable",
type: "constructor",
},
{
inputs: [],
name: "AlreadyCompleted",
type: "error",
},
{
inputs: [],
name: "NotOpenToWithdraw",
type: "error",
},
{
inputs: [
{
internalType: "uint256",
name: "deadline",
type: "uint256",
},
{
internalType: "uint256",
name: "currentTimestamp",
type: "uint256",
},
],
name: "TooEarly",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "amount",
type: "uint256",
},
],
name: "WithdrawTransferFailed",
type: "error",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "",
type: "uint256",
},
],
name: "Contribution",
type: "event",
},
{
inputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
name: "balances",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "contribute",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "deadline",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "execute",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [],
name: "fundingRecipient",
outputs: [
{
internalType: "contract FundingRecipient",
name: "",
type: "address",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "openToWithdraw",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "threshold",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "timeLeft",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "withdraw",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
stateMutability: "payable",
type: "receive",
},
],
inheritedFunctions: {},
deployedOnBlock: 6786,
},
FundingRecipient: {
address: "0x59b670e9fA9D0A427751Af201D676719a970857b",
abi: [
{
inputs: [],
name: "complete",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "completed",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
],
inheritedFunctions: {},
deployedOnBlock: 4703,
},
},
11155111: {
CrowdFund: {
address: "0x6DbF57cA13C63f1Ba977405b128120Ded42ee8a7",
abi: [
{
inputs: [
{
internalType: "address",
name: "fundingRecipientAddress",
type: "address",
},
],
stateMutability: "nonpayable",
type: "constructor",
},
{
inputs: [],
name: "AlreadyCompleted",
type: "error",
},
{
inputs: [],
name: "NotOpenToWithdraw",
type: "error",
},
{
inputs: [
{
internalType: "uint256",
name: "deadline",
type: "uint256",
},
{
internalType: "uint256",
name: "currentTimestamp",
type: "uint256",
},
],
name: "TooEarly",
type: "error",
},
{
inputs: [
{
internalType: "address",
name: "to",
type: "address",
},
{
internalType: "uint256",
name: "amount",
type: "uint256",
},
],
name: "WithdrawTransferFailed",
type: "error",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "",
type: "address",
},
{
indexed: false,
internalType: "uint256",
name: "",
type: "uint256",
},
],
name: "Contribution",
type: "event",
},
{
inputs: [
{
internalType: "address",
name: "",
type: "address",
},
],
name: "balances",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "contribute",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "deadline",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "execute",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [],
name: "fundingRecipient",
outputs: [
{
internalType: "contract FundingRecipient",
name: "",
type: "address",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "openToWithdraw",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "threshold",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "timeLeft",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "withdraw",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
stateMutability: "payable",
type: "receive",
},
],
inheritedFunctions: {},
deployedOnBlock: 10021915,
},
FundingRecipient: {
address: "0xeA89D4E3dA2eb001631dD1c0CFa0D922869D1836",
abi: [
{
inputs: [],
name: "complete",
outputs: [],
stateMutability: "payable",
type: "function",
},
{
inputs: [],
name: "completed",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
],
inheritedFunctions: {},
deployedOnBlock: 10021914,
},
},
} as const;
export default deployedContracts satisfies GenericContractsDeclaration;

View File

@@ -1,6 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View File

@@ -15,7 +15,7 @@ export const DEFAULT_ALCHEMY_API_KEY = "cR4WnXePioePZ5fFrnSiR";
const scaffoldConfig = {
// The networks on which your DApp is live
targetNetworks: [chains.hardhat],
targetNetworks: [chains.sepolia],
// The interval at which your front-end polls the RPC servers for new data (it has no effect if you only target the local network (default is 4000))
pollingInterval: 30000,
// This is ours Alchemy's default API key.
@@ -34,7 +34,7 @@ const scaffoldConfig = {
// It's recommended to store it in an env variable:
// .env.local for local testing, and in the Vercel/system env config for live apps.
walletConnectProjectId: process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID || "3a8170812b534d0ff9d794f19a901d64",
onlyLocalBurnerWallet: true,
onlyLocalBurnerWallet: false, //true,
} as const satisfies ScaffoldConfig;
export default scaffoldConfig;