@@ -3,10 +3,25 @@ pragma experimental ABIEncoderV2;
3
3
4
4
import "./SchemeConstraints.sol " ;
5
5
6
-
7
6
contract DxDaoSchemeConstraints is SchemeConstraints {
8
7
using SafeMath for uint256 ;
9
8
9
+ event UpdatedContractsWhitelist (
10
+ address [] _contractsAddresses ,
11
+ bool [] _contractsWhitelisted
12
+ );
13
+
14
+ event UpdatedPeriodLimitsTokens (
15
+ address [] _tokensAddresses ,
16
+ uint256 [] _tokensPeriodLimits
17
+ );
18
+
19
+ event UpdatedPeriodLimitWei (
20
+ uint256 _periodLimitWei
21
+ );
22
+
23
+ address public avatar;
24
+ address public genericSchemeMultiCall;
10
25
uint256 public initialTimestamp;
11
26
uint256 public periodSize;
12
27
uint256 public periodLimitWei;
@@ -18,26 +33,32 @@ contract DxDaoSchemeConstraints is SchemeConstraints {
18
33
bytes4 private constant APPROVE_SIGNATURE = 0x095ea7b3 ;//approve(address,uint256)
19
34
20
35
/* @dev initialize
36
+ * @param avatar the DAOs avatar address
21
37
* @param _periodSize the time period to limit the tokens and eth spending
22
38
* @param _periodLimitWei the limit of eth which can be sent per period
23
39
* @param _periodLimitTokensAddresses tokens to limit
24
40
* @param _periodLimitTokensAmounts the limit of token which can be sent per period
25
41
* @param _contractsWhiteList the contracts the scheme is allowed to interact with
42
+ * @param _genericSchemeMultiCall genericSchemeMultiCall which allowed to call isAllowedToCall
26
43
*/
27
44
function initialize (
45
+ address _avatar ,
28
46
uint256 _periodSize ,
29
47
uint256 _periodLimitWei ,
30
48
address [] calldata _periodLimitTokensAddresses ,
31
49
uint256 [] calldata _periodLimitTokensAmounts ,
32
- address [] calldata _contractsWhiteList
50
+ address [] calldata _contractsWhiteList ,
51
+ address _genericSchemeMultiCall
33
52
)
34
53
external {
35
54
require (initialTimestamp == 0 , "cannot initialize twice " );
36
55
require (_periodSize > 0 , "preriod size should be greater than 0 " );
37
56
require (_periodLimitTokensAddresses.length == _periodLimitTokensAmounts.length ,
38
57
"invalid length _periodLimitTokensAddresses " );
58
+ require (_genericSchemeMultiCall != address (0 ), "genericSchemeMultiCall cannot be zero " );
39
59
periodSize = _periodSize;
40
60
periodLimitWei = _periodLimitWei;
61
+ avatar = _avatar;
41
62
// solhint-disable-next-line not-rely-on-time
42
63
initialTimestamp = block .timestamp ;
43
64
for (uint i = 0 ; i < _contractsWhiteList.length ; i++ ) {
@@ -47,6 +68,55 @@ contract DxDaoSchemeConstraints is SchemeConstraints {
47
68
periodLimitToken[_periodLimitTokensAddresses[i]] = _periodLimitTokensAmounts[i];
48
69
}
49
70
contractsWhiteList = _contractsWhiteList;
71
+ genericSchemeMultiCall = _genericSchemeMultiCall;
72
+ }
73
+
74
+ /*
75
+ * @dev updateContractWhitelist used to let the DAO update whitelisted contracts.
76
+ * @param _contractsAddresses - The contract that should be update
77
+ * @param _contractsWhitelisted – true adds a contract to the whitelist, false removes it.
78
+ */
79
+ function updateContractsWhitelist (
80
+ address [] calldata _contractsAddresses ,
81
+ bool [] calldata _contractsWhitelisted
82
+ )
83
+ external {
84
+ require (msg .sender == avatar, "caller must be avatar " );
85
+ require (_contractsAddresses.length == _contractsWhitelisted.length ,
86
+ "invalid length _periodLimitTokensAddresses " );
87
+ for (uint i = 0 ; i < _contractsAddresses.length ; i++ ) {
88
+ contractsWhiteListMap[_contractsAddresses[i]] = _contractsWhitelisted[i];
89
+ }
90
+ emit UpdatedContractsWhitelist (_contractsAddresses, _contractsWhitelisted);
91
+ }
92
+
93
+ /*
94
+ * @dev updatePeriodLimitsTokens lets the dao update limits to token limits.
95
+ * @param _tokensAddresses - The token addresses to be updated
96
+ * @param _tokensPeriodLimits – The token amounts to be set as period limit.
97
+ */
98
+ function updatePeriodLimitsTokens (
99
+ address [] calldata _tokensAddresses ,
100
+ uint256 [] calldata _tokensPeriodLimits
101
+ )
102
+ external {
103
+ require (msg .sender == avatar, "caller must be avatar " );
104
+ require (_tokensAddresses.length == _tokensPeriodLimits.length ,
105
+ "invalid length _tokensPeriodLimits " );
106
+ for (uint i = 0 ; i < _tokensAddresses.length ; i++ ) {
107
+ periodLimitToken[_tokensAddresses[i]] = _tokensPeriodLimits[i];
108
+ }
109
+ emit UpdatedPeriodLimitsTokens (_tokensAddresses, _tokensPeriodLimits);
110
+ }
111
+
112
+ /*
113
+ * @dev updatePeriodLimitWei lets the dao update limits to ETH spending limit.
114
+ * @param _periodLimitWei - The new spending limit in WEI that should be set.
115
+ */
116
+ function updatePeriodLimitWei (uint256 _periodLimitWei ) external {
117
+ require (msg .sender == avatar, "caller must be avatar " );
118
+ periodLimitWei = _periodLimitWei;
119
+ emit UpdatedPeriodLimitWei (_periodLimitWei);
50
120
}
51
121
52
122
/*
@@ -68,10 +138,11 @@ contract DxDaoSchemeConstraints is SchemeConstraints {
68
138
external
69
139
returns (bool )
70
140
{
71
-
141
+ require ( msg . sender == genericSchemeMultiCall, " only genericSchemeMultiCall " );
72
142
uint256 observervationIndex = observationIndex ();
73
143
uint256 totalPeriodSpendingInWei;
74
144
for (uint i = 0 ; i < _contractsToCall.length ; i++ ) {
145
+ require (contractsWhiteListMap[_contractsToCall[i]], "contract not whitelisted " );
75
146
// constraint eth transfer
76
147
totalPeriodSpendingInWei = totalPeriodSpendingInWei.add (_values[i]);
77
148
bytes memory callData = _callsData[i];
@@ -81,11 +152,14 @@ contract DxDaoSchemeConstraints is SchemeConstraints {
81
152
callData[2 ] == APPROVE_SIGNATURE[2 ] &&
82
153
callData[3 ] == APPROVE_SIGNATURE[3 ]) {
83
154
uint256 amount;
155
+ address spender;
84
156
address contractToCall = _contractsToCall[i];
85
157
// solhint-disable-next-line no-inline-assembly
86
158
assembly {
87
- amount := mload (add (callData, 68 ))
159
+ spender := mload (add (callData, 36 ))
160
+ amount := mload (add (callData, 68 ))
88
161
}
162
+ require (contractsWhiteListMap[spender], "spender contract not whitelisted " );
89
163
periodSpendingToken[observervationIndex][contractToCall] =
90
164
periodSpendingToken[observervationIndex][contractToCall].add (amount);
91
165
require (
@@ -118,18 +192,13 @@ contract DxDaoSchemeConstraints is SchemeConstraints {
118
192
returns (bool )
119
193
{
120
194
for (uint i = 0 ; i < _contractsToCall.length ; i++ ) {
121
- if (! contractsWhiteListMap[_contractsToCall[i]]) {
195
+ require (contractsWhiteListMap[_contractsToCall[i]], "contract not whitelisted " );
196
+ bytes memory callData = _callsData[i];
197
+ if (callData[0 ] == APPROVE_SIGNATURE[0 ] &&
198
+ callData[1 ] == APPROVE_SIGNATURE[1 ] &&
199
+ callData[2 ] == APPROVE_SIGNATURE[2 ] &&
200
+ callData[3 ] == APPROVE_SIGNATURE[3 ]) {
122
201
address spender;
123
- bytes memory callData = _callsData[i];
124
- require (
125
- callData[0 ] == APPROVE_SIGNATURE[0 ] &&
126
- callData[1 ] == APPROVE_SIGNATURE[1 ] &&
127
- callData[2 ] == APPROVE_SIGNATURE[2 ] &&
128
- callData[3 ] == APPROVE_SIGNATURE[3 ],
129
- "allow only approve call for none whitelistedContracts " );
130
- //in solidity > 6 this can be replaced by:
131
- //(spender,) = abi.descode(callData[4:], (address, uint));
132
- // see https://github.com/ethereum/solidity/issues/9439
133
202
// solhint-disable-next-line no-inline-assembly
134
203
assembly {
135
204
spender := mload (add (callData, 36 ))
0 commit comments