generated from ethereum-optimism/scaffold-op
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
first version of smart contract with user registration
- Loading branch information
1 parent
8ec29d6
commit 28ea1e5
Showing
2 changed files
with
202 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"]; |