-
Notifications
You must be signed in to change notification settings - Fork 10
/
freelancer.sol
169 lines (144 loc) · 4.45 KB
/
freelancer.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/**
* @file freelance.sol
* @author Jackson Ng <jackson@jacksonng.org>
* @date created 17th Apr 2021
* @date last modified 18th Apr 2021
*/
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract freelancer{
enum ScheduleState {planned, funded, started, approved, released}
enum ProjectState {initiated, accepted, closed}
struct schedule{
string shortCode;
string description;
uint256 value;
ScheduleState scheduleState;
}
int256 public totalSchedules = 0;
address payable public freelancerAddress;
address public clientAddress;
ProjectState public projectState;
mapping(int256 => schedule) public scheduleRegister;
modifier condition(bool _condition) {
require(_condition);
_;
}
modifier onlyFreelancer() {
require(msg.sender == freelancerAddress);
_;
}
modifier onlyClient() {
require(msg.sender == clientAddress);
_;
}
modifier bothClientFreelancer(){
require(msg.sender == clientAddress || msg.sender == freelancerAddress);
_;
}
modifier inProjectState(ProjectState _state) {
require(projectState == _state);
_;
}
modifier inScheduleState(int256 _scheduleID, ScheduleState _state){
require((_scheduleID <= totalSchedules - 1) && scheduleRegister[_scheduleID].scheduleState == _state);
_;
}
modifier ampleFunding(int256 _scheduleID, uint256 _funding){
require(scheduleRegister[_scheduleID].value == _funding);
_;
}
modifier noMoreFunds(){
require(address(this).balance == 0);
_;
}
event scheduleAdded(string shortCode);
event projectAccepted(address clientAddress);
event taskFunded(int256 scheduleID);
event taskStarted(int256 scheduleID);
event taskApproved(int256 scheduleID);
event fundsReleased(int256 scheduleID, uint256 valueReleased);
event projectEnded();
constructor()
{
freelancerAddress = payable(msg.sender);
projectState = ProjectState.initiated;
}
function addSchedule(string memory _shortCode, string memory _description, uint256 _value)
public
inProjectState(ProjectState.initiated)
onlyFreelancer
{
schedule memory s;
s.shortCode = _shortCode;
s.description = _description;
s.scheduleState = ScheduleState.planned;
s.value = _value;
scheduleRegister[totalSchedules] = s;
totalSchedules++;
emit scheduleAdded(_shortCode);
}
function acceptProject()
public
inProjectState(ProjectState.initiated)
{
clientAddress = msg.sender;
projectState = ProjectState.accepted;
emit projectAccepted(msg.sender);
}
function fundTask(int256 _scheduleID)
public
payable
inProjectState(ProjectState.accepted)
inScheduleState(_scheduleID, ScheduleState.planned)
ampleFunding(_scheduleID, msg.value)
onlyClient
{
scheduleRegister[_scheduleID].scheduleState = ScheduleState.funded;
emit taskFunded(_scheduleID);
}
function startTask(int256 _scheduleID)
public
inProjectState(ProjectState.accepted)
inScheduleState(_scheduleID, ScheduleState.funded)
onlyFreelancer
{
scheduleRegister[_scheduleID].scheduleState = ScheduleState.started;
emit taskStarted(_scheduleID);
}
function approveTask(int256 _scheduleID)
public
inProjectState(ProjectState.accepted)
inScheduleState(_scheduleID, ScheduleState.started)
onlyClient
{
scheduleRegister[_scheduleID].scheduleState = ScheduleState.approved;
emit taskApproved(_scheduleID);
}
function releaseFunds(int256 _scheduleID)
public
payable
inProjectState(ProjectState.accepted)
inScheduleState(_scheduleID, ScheduleState.approved)
onlyFreelancer
{
freelancerAddress.transfer(scheduleRegister[_scheduleID].value);
scheduleRegister[_scheduleID].scheduleState = ScheduleState.released;
emit fundsReleased(_scheduleID, scheduleRegister[_scheduleID].value);
}
function endProject()
public
bothClientFreelancer
noMoreFunds
{
projectState = ProjectState.closed;
emit projectEnded();
}
function getBalance()
public
view
returns (uint256 balance)
{
return address(this).balance;
}
}