Created
April 6, 2021 02:19
-
-
Save Turupawn/a9fbe65205d5b77a9d29dc02977ba1dd to your computer and use it in GitHub Desktop.
This file contains hidden or 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
pragma solidity ^0.8.0; | |
contract HackathonMunon | |
{ | |
function add(uint256 a, uint256 b) internal pure returns (uint256) { | |
return a + b; | |
} | |
function add8(uint32 a, uint32 b) internal pure returns (uint32) { | |
return a + b; | |
} | |
function sub8(uint32 a, uint32 b) internal pure returns (uint32) { | |
return a - b; | |
} | |
function mul(uint256 a, uint256 b) internal pure returns (uint256) { | |
return a * b; | |
} | |
function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
return a / b; | |
} | |
// Structs | |
struct Hackathon | |
{ | |
uint256 entry_fee; | |
uint256 pot; | |
bytes16 name; | |
address host_addr; | |
bytes16 image_hash; | |
HackathonState state; | |
} | |
struct Participant | |
{ | |
address addr; | |
uint32 points; | |
} | |
// Enums | |
enum HackathonState { RegistrationOpen, ReviewEnabled, Finished } | |
// Public variables | |
mapping(uint32 => Hackathon) public hackathons; // Stores hackathons data | |
mapping(uint32 => mapping(address => Participant)) public hackathon_participants; // Stores participant data | |
mapping(uint32 => address[]) public hackathon_participant_addresses; // Stores participant addresses | |
// Rating history, enables correcting ratings and prevents rating | |
mapping(uint32 => mapping(address => mapping(address => uint32))) public participant_ratings; | |
uint32 public hackathon_count; // Helps generating a new hackathon id | |
mapping(uint32 => mapping(address => bool)) public participant_has_cashed_out; // Helps preventing double cash out | |
mapping(uint32 => uint32) public total_hackathon_points; // Helps calculating pot splits | |
// Modifiers | |
modifier hasJoined(uint32 hackathon_id) | |
{ | |
require(hackathon_participants[hackathon_id][msg.sender].addr != address(0)); | |
_; | |
} | |
// Public methods | |
function createHackathon(bytes16 _name, bytes16 image_hash, uint256 _entry_fee) public | |
{ | |
hackathon_count += 1; | |
hackathons[hackathon_count] = Hackathon(_entry_fee, 0, _name, image_hash, msg.sender, HackathonState.RegistrationOpen); | |
} | |
function join( | |
uint32 hackathon_id | |
) public payable | |
{ | |
require(hackathons[hackathon_id].state == HackathonState.RegistrationOpen); | |
require(hackathon_participants[hackathon_id][msg.sender].addr == address(0)); | |
require(msg.value == hackathons[hackathon_id].entry_fee); | |
Participant memory participant = Participant(msg.sender, 0); | |
hackathon_participants[hackathon_id][msg.sender] = participant; | |
hackathon_participant_addresses[hackathon_id].push(msg.sender); | |
hackathons[hackathon_id].pot = add(hackathons[hackathon_id].pot,(hackathons[hackathon_id].entry_fee)); | |
} | |
function sponsor( | |
uint32 hackathon_id | |
) public payable | |
{ | |
require(hackathons[hackathon_id].state != HackathonState.Finished); | |
hackathons[hackathon_id].pot = add(hackathons[hackathon_id].pot,(msg.value)); | |
} | |
function rateAll( | |
uint32 hackathon_id, | |
uint32[] memory points | |
) public hasJoined(hackathon_id) | |
{ | |
require(hackathons[hackathon_id].state == HackathonState.ReviewEnabled); | |
for (uint i=0; i<hackathon_participant_addresses[hackathon_id].length; i++) { | |
require(points[i] <= 5); | |
} | |
require(points.length == hackathon_participant_addresses[hackathon_id].length); | |
for (uint i=0; i<hackathon_participant_addresses[hackathon_id].length; i++) { | |
address reviewed_address = hackathon_participant_addresses[hackathon_id][i]; | |
uint32 rating_stored = participant_ratings[hackathon_id][msg.sender][reviewed_address]; | |
hackathon_participants[hackathon_id][reviewed_address].points = add8(hackathon_participants[hackathon_id][reviewed_address].points,sub8(points[i],(rating_stored))); | |
total_hackathon_points[hackathon_id] = add8(total_hackathon_points[hackathon_id],sub8(points[i],rating_stored)); | |
participant_ratings[hackathon_id][msg.sender][reviewed_address] = points[i]; | |
} | |
} | |
function cashOut(uint32 hackathon_id) | |
public hasJoined(hackathon_id) | |
{ | |
require(hackathons[hackathon_id].state == HackathonState.Finished); | |
require(!participant_has_cashed_out[hackathon_id][msg.sender]); | |
uint32 total_points = total_hackathon_points[hackathon_id]; | |
uint32 my_points = hackathon_participants[hackathon_id][msg.sender].points; | |
// Calculate reward | |
uint256 pot = hackathons[hackathon_id].pot; | |
uint256 my_reward = mul(pot,div(my_points,total_points)); | |
payable(msg.sender).transfer(my_reward); | |
participant_has_cashed_out[hackathon_id][msg.sender] = true; | |
} | |
function enableHackathonReview(uint32 hackathon_id) public | |
{ | |
require(hackathons[hackathon_id].host_addr == msg.sender); | |
hackathons[hackathon_id].state = HackathonState.ReviewEnabled; | |
} | |
function finishHackathon(uint32 hackathon_id) public | |
{ | |
require(hackathons[hackathon_id].host_addr == msg.sender); | |
hackathons[hackathon_id].state = HackathonState.Finished; | |
} | |
fallback () external payable { | |
revert(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment