Skip to content

Commit

Permalink
Update KindKoin_DonationHub contract
Browse files Browse the repository at this point in the history
  • Loading branch information
naiirad committed Nov 28, 2023
1 parent 6fe4cf9 commit aeedc56
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 13 deletions.
38 changes: 26 additions & 12 deletions packages/hardhat/contracts/KindKoin_DonationHub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ pragma solidity >=0.8.0 <0.9.0;
// Hardhat console for debugging purposes. Remove this import for production deployment.
import "hardhat/console.sol";

// Importing OpenZeppelin's Ownable and pausable contract for access control and emergency stop functionalities.
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol"; // for access control
import "@openzeppelin/contracts/security/Pausable.sol"; // for emergency stop functionalities
import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; // for preventing reentrancy attacks


// The KindKoin_DonationHub contract for handling project donations.
contract KindKoin_DonationHub is Ownable, Pausable {
contract KindKoin_DonationHub is Ownable, Pausable, ReentrancyGuard {
// Project struct to hold each project's wallet address and total donations received.
struct Project {
address payable wallet;
uint totalDonations;
uint pendingWithdrawals;
}

// Variable to store the service fee percentage. Initialized to 1%.
Expand All @@ -31,12 +33,13 @@ contract KindKoin_DonationHub is Ownable, Pausable {

// Function to add a new project. Existing projects cannot be updated (wallet address is immutable).
function setProject(uint projectId, address payable projectWallet) public onlyOwner whenNotPaused {
require(projectId >= 0 && projectId < maxProjectCount, "Invalid project ID or exceeds max limit");
require(projectWallet != address(0), "Invalid wallet address");
require(projects[projectId].wallet == address(0), "Project already exists");

projects[projectId] = Project(projectWallet, 0);
}
require(projectId >= 0 && projectId < maxProjectCount, "Invalid project ID or exceeds max limit");
require(projectWallet != address(0), "Invalid wallet address");
require(projects[projectId].wallet == address(0), "Project already exists");

// Initialize 'pendingWithdrawals' with 0, together with 'wallet' and 'totalDonations'
projects[projectId] = Project(projectWallet, 0, 0);
}

// Function to remove a project from the platform.
function removeProject(uint projectId) public onlyOwner whenNotPaused {
Expand All @@ -53,16 +56,16 @@ contract KindKoin_DonationHub is Ownable, Pausable {
}

// Function to handle donation transactions to a specific project.
function donate(uint projectId) public payable whenNotPaused {
function donate(uint projectId) public payable whenNotPaused nonReentrant {
require(msg.value > 0, "Donation must be greater than 0");
require(projects[projectId].wallet != address(0), "Project does not exist");
require(gasleft() >= 2300, "Insufficient gas");

uint fee = (msg.value * serviceFeePercentage) / 1000; // Calculating the fee
uint donationAmount = msg.value - fee;

projects[projectId].wallet.transfer(donationAmount);
projects[projectId].totalDonations += donationAmount;
projects[projectId].pendingWithdrawals += donationAmount; // Update of outstanding withdrawals

userTotalDonations[msg.sender] += donationAmount;

Expand All @@ -71,6 +74,17 @@ contract KindKoin_DonationHub is Ownable, Pausable {
emit DonationMade(msg.sender, projectId, donationAmount);
}

// Function for projects to withdraw their donations
function withdrawDonations(uint projectId) public nonReentrant {
Project storage project = projects[projectId];
require(msg.sender == project.wallet, "Only project wallet can withdraw");
require(project.pendingWithdrawals > 0, "No funds to withdraw");

uint amount = project.pendingWithdrawals;
project.pendingWithdrawals = 0;
project.wallet.transfer(amount);
}

// Functions for pausing and resuming the contract
function pause() public onlyOwner {
_pause();
Expand Down
82 changes: 81 additions & 1 deletion packages/nextjs/contracts/deployedContracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract";
const deployedContracts = {
31337: {
KindKoin_DonationHub: {
address: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9",
address: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
abi: [
{
anonymous: false,
Expand Down Expand Up @@ -53,6 +53,32 @@ const deployedContracts = {
name: "OwnershipTransferred",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "account",
type: "address",
},
],
name: "Paused",
type: "event",
},
{
anonymous: false,
inputs: [
{
indexed: false,
internalType: "address",
name: "account",
type: "address",
},
],
name: "Unpaused",
type: "event",
},
{
inputs: [
{
Expand Down Expand Up @@ -136,6 +162,19 @@ const deployedContracts = {
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "maxProjectCount",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "owner",
Expand All @@ -149,6 +188,26 @@ const deployedContracts = {
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "pause",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [],
name: "paused",
outputs: [
{
internalType: "bool",
name: "",
type: "bool",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
Expand Down Expand Up @@ -213,11 +272,32 @@ const deployedContracts = {
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [],
name: "unpause",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "uint256",
name: "projectId",
type: "uint256",
},
],
name: "withdrawDonations",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
],
inheritedFunctions: {
owner: "@openzeppelin/contracts/access/Ownable.sol",
renounceOwnership: "@openzeppelin/contracts/access/Ownable.sol",
transferOwnership: "@openzeppelin/contracts/access/Ownable.sol",
paused: "@openzeppelin/contracts/security/Pausable.sol",
},
},
},
Expand Down

0 comments on commit aeedc56

Please sign in to comment.