Skip to content

Instantly share code, notes, and snippets.

@Turupawn
Created April 6, 2021 02:19
Show Gist options
  • Save Turupawn/a9fbe65205d5b77a9d29dc02977ba1dd to your computer and use it in GitHub Desktop.
Save Turupawn/a9fbe65205d5b77a9d29dc02977ba1dd to your computer and use it in GitHub Desktop.
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