Olympics & Competitions
Olympics DAO consists a set of smart contracts that aim to implement a truly decentralized competition management.

Overview

Olympics

The Olympics contract is managing the community and the competitions. When an Olympics contract is deployed, it also deploys an instance of Community (see below). The Olympics contract consists the functions for creating competition, closing competition (once finished), and fetching all the competitions within the Olympics.
A modified onlyOlympicsCoreTeam is used to ensure access to the functions for managing the competitions.
1
modifier onlyOlympicsCoreTeam() {
2
require(
3
community.isCoreTeamMember(msg.sender),
4
"Only Olympics Core Team can call this"
5
);
6
_;
7
}
Copied!
Only a SkillWallet holder, that's marked as a core team member can call those functions.
1
function createCompetition(
2
uint256 role,
3
uint256 skill1,
4
uint256 skill2,
5
uint256 skill3,
6
string calldata metadata,
7
uint startTime,
8
uint endTime
9
) external;
10
​
11
function getCompetitions() external view returns (address[] memory);
12
​
Copied!

Community

Olympics DAO uses SkillWallet implementation of community with a single difference that there is no high cap on members allowed. Everyone can join and participate in a competition. The community has the concept of core team members. An attribute called onlyCoreTeam member is used to secure the functions that can be called only by the team.
​
1
modifier onlyCoreTeam() {
2
require(
3
isCoreTeamMember[msg.sender],
4
"The signer is not whitelisted as core team member!"
5
);
6
require(
7
skillWallet.balanceOf(msg.sender) > 0,
8
"SkillWallet not created by the whitelisted member"
9
);
10
_;
11
}
Copied!
For more information about the community please visit [link].

Competition

Once a user has created their SkillWallet and is part of the Olympics DAO community, they can also join a competition. One Olympics instance has multiple competitions that can be created by core team members. When a core team member calls createCompetition function, a Competition contract is deployed and is assigned to this specific Olympics contract. Each competition is assigned to a role and skill. Each Olympics community has 3 roles, and each role has 4 skills. There are 12 competitions in total covering all the skills within these roles.
Each competition can be associated with one role and up to 3 skills.
Each competition has a partner/co-host. The core team members of Olympics DAO can be added to the cohost whitelist of the competition. This gives them rights to set the winners, create checkpoints and pass checkpoints for a member.
The competition contract is managing the participants, cohosts and skills.
1
string public metadataUri;
2
​
3
address[] participants;
4
address[] partners;
5
mapping(address => bool) public override isParticipant;
6
mapping(address => bool) public override isPartner;
7
​
8
​
9
uint256 public role;
10
uint256[] public skills;
11
mapping(uint256 => bool) public isCompetitionSkill;
12
uint256 public startDate;
13
uint256 public endDate;
Copied!
Only a SkillWallet holder that's a part of the Olympics Community can join a competition.
Each competition has off-chain metadata that's stored as a JSON file on IPFS and the CID is assigned to the competition. This off-chain metadata holds information such as Name, Description, Competition Logo etc.
Within competition, there are three modifiers managing the permissions to the functions within the contract - onlyOlympicsCoreTeam that you've seen above and onlyParticipant , and onlyPartner.
1
modifier onlyParticipant() {
2
require(isParticipant[msg.sender], "Only participants can call this!");
3
_;
4
}
5
​
6
modifier onlyPartner() {
7
require(isPartner[msg.sender], "Only partner member can call this!");
8
_;
9
}
Copied!
Competition.sol implements the following interface:
interface ICompetition { event ParticipantAdded( address indexed _member, uint256 _skillWalletTokenId, uint256 competitionID );
1
​
2
/**
3
* @title Olympics DAO Competition
4
*
5
* @dev ICompetition interface
6
* @author SkillWallet
7
*/
8
​
9
interface ICompetition {
10
event PartnerMemberAdded();
11
event CheckpointCreated();
12
event CheckpointPassed();
13
event ParticipantAdded(address indexed _member);
14
​
15
/**
16
@dev Adds a member of the Olympics DAO to the competition.
17
access: public (will fail if the signer is not a part of the OlympicsDAO Community)
18
*/
19
function join() external;
20
​
21
​
22
function addPartnerMemberToCompetition(address member) external;
23
​
24
/**
25
@dev Creates a checkpoint for the competition. Assigns the off chain metadata to the checkpoint.
26
@param metadata - off-chain metadata stored on IPFS as a JSON file
27
access: only core team members
28
*/
29
function createCheckpoint(
30
string memory metadata,
31
uint256 startDate,
32
uint256 endDate,
33
uint256[3] calldata skills
34
) external;
35
​
36
/**
37
@dev Returns list of the addresses of the participants
38
@return address[] memory
39
access: public
40
*/
41
function getParticipants() external returns (address[] memory);
42
​
43
/**
44
@dev Returns list of the addresses of the partners members
45
@return address[] memory
46
access: public
47
*/
48
function getPartnerMembers() external returns (address[] memory);
49
​
50
/**
51
@dev Returns whether a competition is ongoing.
52
@return bool is ongoing?
53
access: public
54
*/
55
function isOngoing() external view returns (bool);
56
​
57
​
58
/**
59
@dev
60
@return bool if the passed address is a participanting in the competition
61
access: public
62
*/
63
function isParticipant(address member) external view returns (bool);
64
​
65
/**
66
@dev
67
@return bool if the passed address is a partner member in the competition
68
access: public
69
*/
70
function isPartner(address member) external view returns (bool);
71
}
Copied!
Olympics DAO is implementing progressive decentralisation. In the beginning, the voting is done by core team members adding a ranking each participant of a competition. With the next Olympics DAO upgrade, there will be a voting mechanism introduced that will replace this. Before that the partners will be able to set the winners of the competition.

Checkpoint

In order for a participant to complete successfully a competition, they need to pass all the checkpoints. By passing checkpoints the participants build their skill level.
After a participant passes a checkpoint, one of the core team members should mark it as passed in order for the participant to get their skill level updated.
1
​
2
/**
3
* @title Olympics DAO ICheckpoint
4
*
5
* @dev ICheckpoint interface
6
* @author SkillWallet
7
*/
8
interface ICheckpoint {
9
​
10
event CheckpointCreated(uint256 checkpointID, address competitionAddress);
11
event CheckpointPassed(uint256 checkpointID, address userAddress);
12
​
13
/**
14
@dev Creates a new checkpoint for a specific competition.
15
@param metadata - off-chain metadata of the checkpoint stored on IPFS
16
access: only core team members
17
*/
18
function create(
19
string calldata metadata,
20
uint256 startDate,
21
uint256 endDate,
22
uint256[3] calldata skills,
23
uint role
24
) external;
25
​
26
/**
27
@dev Marks a checkpoint as passed by the participant.
28
returns bool if the passed address is a participanting in the competition
29
@param checkpointID - participant address
30
@param user - participant address
31
access: only core team members
32
*/
33
function pass(uint256 checkpointID, address user) external;
34
​
35
/**
36
@dev Fetches all checkpoints per competition
37
returns uint256[] memory checkpoints - checkpoint IDs
38
@param competition The address of the competition
39
access: public
40
*/
41
function getCheckpointsPerCompetition(address competition)
42
external
43
view
44
returns (uint256[] memory checkpoints);
45
​
46
function hasAParticipantPassedTheCheckpoint(
47
uint256 checkpointID,
48
address member
49
) external view returns (bool);
50
​
51
function hasSkill(
52
uint256 checkpointID,
53
uint256 role,
54
uint256 skill
55
) external view returns (bool);
56
}
Copied!

CommunitySkill.sol

The CommunitySkill contract is responsible for calculating the skill level of a member of the Olympics DAO, depending on the checkpoints passed.
It implements the following interface:
1
/**
2
* @title SkillWallet CommunitySkills
3
*
4
* @dev Implementation of the CommunitySkills concept in the scope of the SkillWallet project
5
* @author SkillWallet
6
*/
7
​
8
interface ICommunitySkills {
9
​
10
function calculateSkillLevel(
11
address member,
12
uint256 role,
13
uint256 skill
14
) external;
15
​
16
function getSkillLevel(
17
address member,
18
uint256 role,
19
uint256 skill
20
) external view returns (uint256);
21
}
Copied!
The skill level is calculated with the following formula:
where the checkpoints taken into consideration, are only the ones associated to the role <-> skill which is calculated.