Skip to content

Commit 7d6ce3a

Browse files
nicoelzerOren Sokolowskyorenyodfat
authored
Added upgradable contraintLimits (#798)
* simplify contract * tests * test approval * check spender is white listed * clean * poc * Add SchemeConstraints interface * add eth constraint as an example for DxDaoSchemeConstraint * + * more .. * fix dxdao constraints * check schemeConstraint exist * + comments * coverage * Added upgradable contraintLimits * updated genericschmemulticall tests * Updated DXdaoSchemeConstraints * Added contraint events and smaller updates * Added additional tests for DxDaoSchemeConstraints * rebase from arc/master * Updated DxDaoSchemeContraints events & general cleanup * solhint cleanup * cleanup * Fixed test issues * updated DxDaoSchemeConstraints.sol * only genericSchemeMultiCall can call isAllowToCall test coverage * comments * Added additional test for GenericSchemeMultiCall Co-authored-by: Oren Sokolowsky <[email protected]> Co-authored-by: orenyodfat <[email protected]>
1 parent 19682c2 commit 7d6ce3a

File tree

2 files changed

+484
-46
lines changed

2 files changed

+484
-46
lines changed

contracts/schemes/DxDaoSchemeConstraints.sol

Lines changed: 84 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,25 @@ pragma experimental ABIEncoderV2;
33

44
import "./SchemeConstraints.sol";
55

6-
76
contract DxDaoSchemeConstraints is SchemeConstraints {
87
using SafeMath for uint256;
98

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;
1025
uint256 public initialTimestamp;
1126
uint256 public periodSize;
1227
uint256 public periodLimitWei;
@@ -18,26 +33,32 @@ contract DxDaoSchemeConstraints is SchemeConstraints {
1833
bytes4 private constant APPROVE_SIGNATURE = 0x095ea7b3;//approve(address,uint256)
1934

2035
/* @dev initialize
36+
* @param avatar the DAOs avatar address
2137
* @param _periodSize the time period to limit the tokens and eth spending
2238
* @param _periodLimitWei the limit of eth which can be sent per period
2339
* @param _periodLimitTokensAddresses tokens to limit
2440
* @param _periodLimitTokensAmounts the limit of token which can be sent per period
2541
* @param _contractsWhiteList the contracts the scheme is allowed to interact with
42+
* @param _genericSchemeMultiCall genericSchemeMultiCall which allowed to call isAllowedToCall
2643
*/
2744
function initialize(
45+
address _avatar,
2846
uint256 _periodSize,
2947
uint256 _periodLimitWei,
3048
address[] calldata _periodLimitTokensAddresses,
3149
uint256[] calldata _periodLimitTokensAmounts,
32-
address[] calldata _contractsWhiteList
50+
address[] calldata _contractsWhiteList,
51+
address _genericSchemeMultiCall
3352
)
3453
external {
3554
require(initialTimestamp == 0, "cannot initialize twice");
3655
require(_periodSize > 0, "preriod size should be greater than 0");
3756
require(_periodLimitTokensAddresses.length == _periodLimitTokensAmounts.length,
3857
"invalid length _periodLimitTokensAddresses");
58+
require(_genericSchemeMultiCall != address(0), "genericSchemeMultiCall cannot be zero");
3959
periodSize = _periodSize;
4060
periodLimitWei = _periodLimitWei;
61+
avatar = _avatar;
4162
// solhint-disable-next-line not-rely-on-time
4263
initialTimestamp = block.timestamp;
4364
for (uint i = 0; i < _contractsWhiteList.length; i++) {
@@ -47,6 +68,55 @@ contract DxDaoSchemeConstraints is SchemeConstraints {
4768
periodLimitToken[_periodLimitTokensAddresses[i]] = _periodLimitTokensAmounts[i];
4869
}
4970
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);
50120
}
51121

52122
/*
@@ -68,10 +138,11 @@ contract DxDaoSchemeConstraints is SchemeConstraints {
68138
external
69139
returns(bool)
70140
{
71-
141+
require(msg.sender == genericSchemeMultiCall, "only genericSchemeMultiCall");
72142
uint256 observervationIndex = observationIndex();
73143
uint256 totalPeriodSpendingInWei;
74144
for (uint i = 0; i < _contractsToCall.length; i++) {
145+
require(contractsWhiteListMap[_contractsToCall[i]], "contract not whitelisted");
75146
// constraint eth transfer
76147
totalPeriodSpendingInWei = totalPeriodSpendingInWei.add(_values[i]);
77148
bytes memory callData = _callsData[i];
@@ -81,11 +152,14 @@ contract DxDaoSchemeConstraints is SchemeConstraints {
81152
callData[2] == APPROVE_SIGNATURE[2] &&
82153
callData[3] == APPROVE_SIGNATURE[3]) {
83154
uint256 amount;
155+
address spender;
84156
address contractToCall = _contractsToCall[i];
85157
// solhint-disable-next-line no-inline-assembly
86158
assembly {
87-
amount := mload(add(callData, 68))
159+
spender := mload(add(callData, 36))
160+
amount := mload(add(callData, 68))
88161
}
162+
require(contractsWhiteListMap[spender], "spender contract not whitelisted");
89163
periodSpendingToken[observervationIndex][contractToCall] =
90164
periodSpendingToken[observervationIndex][contractToCall].add(amount);
91165
require(
@@ -118,18 +192,13 @@ contract DxDaoSchemeConstraints is SchemeConstraints {
118192
returns(bool)
119193
{
120194
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]) {
122201
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
133202
// solhint-disable-next-line no-inline-assembly
134203
assembly {
135204
spender := mload(add(callData, 36))

0 commit comments

Comments
 (0)