-
Notifications
You must be signed in to change notification settings - Fork 239
Expand file tree
/
Copy pathDisputableAragonApp.sol
More file actions
161 lines (138 loc) · 7.11 KB
/
Copy pathDisputableAragonApp.sol
File metadata and controls
161 lines (138 loc) · 7.11 KB
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
/*
* SPDX-License-Identifier: MIT
*/
pragma solidity ^0.4.24;
import "./IAgreement.sol";
import "./IDisputable.sol";
import "../AragonApp.sol";
import "../../lib/token/ERC20.sol";
import "../../lib/math/SafeMath64.sol";
contract DisputableAragonApp is IDisputable, AragonApp {
/* Validation errors */
string internal constant ERROR_SENDER_NOT_KERNEL = "DISPUTABLE_SENDER_NOT_KERNEL";
string internal constant ERROR_SENDER_NOT_AGREEMENT = "DISPUTABLE_SENDER_NOT_AGREEMENT";
string internal constant ERROR_AGREEMENT_STATE_INVALID = "DISPUTABLE_AGREEMENT_STATE_INVAL";
// This role is used to protect who can challenge actions in derived Disputable apps. However, it is not required
// to be validated in the app itself as the connected Agreement is responsible for performing the check on a challenge.
// bytes32 public constant CHALLENGE_ROLE = keccak256("CHALLENGE_ROLE");
bytes32 public constant CHALLENGE_ROLE = 0xef025787d7cd1a96d9014b8dc7b44899b8c1350859fb9e1e05f5a546dd65158d;
// bytes32 internal constant AGREEMENT_POSITION = keccak256("aragonOS.appStorage.agreement");
bytes32 internal constant AGREEMENT_POSITION = 0x6dbe80ccdeafbf5f3fff5738b224414f85e9370da36f61bf21c65159df7409e9;
modifier onlyAgreement() {
require(address(_getAgreement()) == msg.sender, ERROR_SENDER_NOT_AGREEMENT);
_;
}
/**
* @notice Challenge disputable action #`_disputableActionId`
* @dev This hook must be implemented by Disputable apps. We provide a base implementation to ensure that the `onlyAgreement` modifier
* is included. Developers of derived Disputable apps should implement an internal abstract implementation of the hook.
* @param _disputableActionId Identifier of the action to be challenged
* @param _challengeId Identifier of the challenge in the context of the Agreement
* @param _challenger Address that submitted the challenge
*/
function onDisputableActionChallenged(uint256 _disputableActionId, uint256 _challengeId, address _challenger) external onlyAgreement {
_onDisputableActionChallenged(_disputableActionId, _challengeId, _challenger);
}
/**
* @notice Allow disputable action #`_disputableActionId`
* @dev This hook must be implemented by Disputable apps. We provide a base implementation to ensure that the `onlyAgreement` modifier
* is included. Developers of derived Disputable apps should implement an internal abstract implementation of the hook.
* @param _disputableActionId Identifier of the action to be allowed
*/
function onDisputableActionAllowed(uint256 _disputableActionId) external onlyAgreement {
_onDisputableActionAllowed(_disputableActionId);
}
/**
* @notice Reject disputable action #`_disputableActionId`
* @dev This hook must be implemented by Disputable apps. We provide a base implementation to ensure that the `onlyAgreement` modifier
* is included. Developers of derived Disputable apps should implement an internal abstract implementation of the hook.
* @param _disputableActionId Identifier of the action to be rejected
*/
function onDisputableActionRejected(uint256 _disputableActionId) external onlyAgreement {
_onDisputableActionRejected(_disputableActionId);
}
/**
* @notice Void disputable action #`_disputableActionId`
* @dev This hook must be implemented by Disputable apps. We provide a base implementation to ensure that the `onlyAgreement` modifier
* is included. Developers of derived Disputable apps should implement an internal abstract implementation of the hook.
* @param _disputableActionId Identifier of the action to be voided
*/
function onDisputableActionVoided(uint256 _disputableActionId) external onlyAgreement {
_onDisputableActionVoided(_disputableActionId);
}
/**
* @notice Set Agreement to `_agreement`
* @param _agreement Agreement instance to be set
*/
function setAgreement(IAgreement _agreement) external {
require(IKernel(msg.sender) == kernel(), ERROR_SENDER_NOT_KERNEL);
IAgreement currentAgreement = _getAgreement();
require(currentAgreement == IAgreement(0) && _agreement != IAgreement(0), ERROR_AGREEMENT_STATE_INVALID);
AGREEMENT_POSITION.setStorageAddress(address(_agreement));
emit AgreementSet(_agreement);
}
/**
* @dev Tell the linked Agreement
* @return Agreement
*/
function getAgreement() external view returns (IAgreement) {
return _getAgreement();
}
/**
* @dev Internal implementation of the `onDisputableActionChallenged` hook
* @param _disputableActionId Identifier of the action to be challenged
* @param _challengeId Identifier of the challenge in the context of the Agreement
* @param _challenger Address that submitted the challenge
*/
function _onDisputableActionChallenged(uint256 _disputableActionId, uint256 _challengeId, address _challenger) internal;
/**
* @dev Internal implementation of the `onDisputableActionRejected` hook
* @param _disputableActionId Identifier of the action to be rejected
*/
function _onDisputableActionRejected(uint256 _disputableActionId) internal;
/**
* @dev Internal implementation of the `onDisputableActionAllowed` hook
* @param _disputableActionId Identifier of the action to be allowed
*/
function _onDisputableActionAllowed(uint256 _disputableActionId) internal;
/**
* @dev Internal implementation of the `onDisputableActionVoided` hook
* @param _disputableActionId Identifier of the action to be voided
*/
function _onDisputableActionVoided(uint256 _disputableActionId) internal;
/**
* @dev Create a new action in the Agreement
* @param _disputableActionId Identifier of the action in the context of the Disputable
* @param _context Link to human-readable context for the given action
* @param _submitter Address that submitted the action
* @return Unique identifier for the created action in the context of the Agreement
*/
function _newAgreementAction(uint256 _disputableActionId, bytes _context, address _submitter) internal returns (uint256) {
IAgreement agreement = _ensureAgreement();
return agreement.newAction.value(msg.value)(_disputableActionId, _context, _submitter);
}
/**
* @dev Close action in the Agreement
* @param _actionId Identifier of the action in the context of the Agreement
*/
function _closeAgreementAction(uint256 _actionId) internal {
IAgreement agreement = _ensureAgreement();
agreement.closeAction(_actionId);
}
/**
* @dev Tell the linked Agreement
* @return Agreement
*/
function _getAgreement() internal view returns (IAgreement) {
return IAgreement(AGREEMENT_POSITION.getStorageAddress());
}
/**
* @dev Tell the linked Agreement or revert if it has not been set
* @return Agreement
*/
function _ensureAgreement() internal view returns (IAgreement) {
IAgreement agreement = _getAgreement();
require(agreement != IAgreement(0), ERROR_AGREEMENT_STATE_INVALID);
return agreement;
}
}