Skip to content

Commit

Permalink
first version of smart contract with user registration
Browse files Browse the repository at this point in the history
  • Loading branch information
bluntbrain committed Aug 3, 2024
1 parent 8ec29d6 commit 28ea1e5
Show file tree
Hide file tree
Showing 2 changed files with 202 additions and 0 deletions.
185 changes: 185 additions & 0 deletions packages/hardhat/contracts/RepoRewards.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

contract RepoRewards is Ownable {
struct PoolManager {
string username;
uint256 githubId;
string worldId;
address wallet;
}

struct Contributor {
string username;
uint256 githubId;
string worldId;
address wallet;
}

struct Issue {
uint256 issueId;
uint256 rewardAmount;
string status;
}

struct Repository {
address[] poolManagers;
address[] contributors;
uint256 poolRewards;
mapping(uint256 => Issue) issueRewards;
}

mapping(address => PoolManager) public poolManagers;
mapping(address => Contributor) public contributors;
mapping(uint256 => Repository) public repositories;

constructor() {}

modifier onlyPoolManager(uint256 repoId) {
require(
isPoolManager(repoId, msg.sender) || owner() == msg.sender,
"Not authorized"
);
_;
}

function isPoolManager(
uint256 repoId,
address manager
) internal view returns (bool) {
Repository storage repo = repositories[repoId];
for (uint i = 0; i < repo.poolManagers.length; i++) {
if (repo.poolManagers[i] == manager) {
return true;
}
}
return false;
}

function registerUser(
string memory username,
uint256 githubId,
string memory worldId,
string memory typeOfUser
) external {
if (
keccak256(abi.encodePacked(typeOfUser)) ==
keccak256(abi.encodePacked("PoolManager"))
) {
poolManagers[msg.sender] = PoolManager(
username,
githubId,
worldId,
msg.sender
);
} else {
contributors[msg.sender] = Contributor(
username,
githubId,
worldId,
msg.sender
);
}
}

function addPoolManager(
uint256 repoId,
address poolManager,
string memory username,
uint256 githubId
) external onlyPoolManager(repoId) {
Repository storage repo = repositories[repoId];
repo.poolManagers.push(poolManager);
poolManagers[poolManager] = PoolManager(
username,
githubId,
"",
poolManager
);
}

function allocateIssueReward(
uint256 repoId,
uint256 issueId,
uint256 reward
) external onlyPoolManager(repoId) {
Repository storage repo = repositories[repoId];
require(repo.poolRewards >= reward, "Insufficient pool rewards");

repo.issueRewards[issueId] = Issue({
issueId: issueId,
rewardAmount: reward,
status: "allocated"
});
repo.poolRewards -= reward;
}

function addFundToRepository(uint256 repoId) external payable {
Repository storage repo = repositories[repoId];
if (repo.poolManagers.length == 0) {
// Create a new repository if it doesn't exist
repositories[repoId].poolManagers = new address[](0);
repositories[repoId].contributors = new address[](0);
// Add the sender as the pool manager
repositories[repoId].poolManagers.push(msg.sender);
}
repositories[repoId].poolRewards += msg.value;
}

function distributeReward(
uint256 repoId,
uint256 issueId,
address payable contributorAddress
) external onlyPoolManager(repoId) {
Repository storage repo = repositories[repoId];
Issue storage issue = repo.issueRewards[issueId];
uint256 reward = issue.rewardAmount;
require(reward > 0, "No reward allocated for this issue");
delete repo.issueRewards[issueId];
require(
address(this).balance >= reward,
"Insufficient contract balance"
);

(bool success, ) = contributorAddress.call{ value: reward }("");
require(success, "Reward transfer failed");
}

// Fallback function to accept Ether
receive() external payable {}

// Getter functions for public mappings
function getPoolManager(
address _wallet
) external view returns (PoolManager memory) {
return poolManagers[_wallet];
}

function getContributor(
address _wallet
) external view returns (Contributor memory) {
return contributors[_wallet];
}

function getRepository(
uint256 _repoId
) external view returns (address[] memory, address[] memory, uint256) {
Repository storage repo = repositories[_repoId];
return (repo.poolManagers, repo.contributors, repo.poolRewards);
}

// Function to check if a user exists and their type
function checkUserType(
address _user
) external view returns (string memory) {
if (poolManagers[_user].wallet != address(0)) {
return "PoolManager";
} else if (contributors[_user].wallet != address(0)) {
return "Contributor";
} else {
return "User does not exist";
}
}
}
17 changes: 17 additions & 0 deletions packages/hardhat/deploy/02_deploy_repo_rewards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";

const deployRepoRewards: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployer } = await hre.getNamedAccounts();
const { deploy } = hre.deployments;

await deploy("RepoRewards", {
from: deployer,
log: true,
autoMine: true,
});
};

export default deployRepoRewards;

deployRepoRewards.tags = ["RepoRewards"];

0 comments on commit 28ea1e5

Please sign in to comment.