Skip to content

Commit 6975ee3

Browse files
committed
Final functions and DAO test implemented.
1 parent 25a2dc7 commit 6975ee3

12 files changed

+800
-221
lines changed

script/Deploy.s.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,17 @@ contract Deploy is Script {
2626
);
2727
SmartnodesCore core = new SmartnodesCore(address(token));
2828

29-
token.setSmartnodesCore(address(core));
3029
token.setDAO(address(dao));
3130

3231
SmartnodesCoordinator coordinator = new SmartnodesCoordinator(
3332
3600,
3433
66,
3534
address(core),
35+
address(token),
3636
initialActiveNodes
3737
);
3838

39+
token.setSmartnodes(address(core), address(coordinator));
3940
core.setCoordinator(address(coordinator));
4041

4142
bytes32 publicKeyHash = vm.envBytes32("PUBLIC_KEY_HASH");

src/SmartnodesCoordinator.sol

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pragma solidity ^0.8.22;
33

44
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
55
import {ISmartnodesCore} from "./interfaces/ISmartnodesCore.sol";
6+
import {ISmartnodesToken} from "./interfaces/ISmartnodesToken.sol";
67

78
/**
89
* @title SmartnodesCoordinator
@@ -13,6 +14,7 @@ contract SmartnodesCoordinator is ReentrancyGuard {
1314
// ============= Errors ==============
1415
error Coordinator__NotValidator();
1516
error Coordinator__NotCoreContract();
17+
error Coordinator__NotTokenContract();
1618
error Coordinator__NotEligibleValidator();
1719
error Coordinator__AlreadySubmittedProposal();
1820
error Coordinator__AlreadyVoted();
@@ -29,6 +31,7 @@ contract SmartnodesCoordinator is ReentrancyGuard {
2931

3032
// ============= State Variables ==============
3133
ISmartnodesCore private immutable i_smartnodesCore;
34+
ISmartnodesToken private immutable i_smartnodesToken;
3235
uint8 private immutable i_requiredApprovalsPercentage;
3336

3437
// Packed time-related variables
@@ -91,6 +94,12 @@ contract SmartnodesCoordinator is ReentrancyGuard {
9194
_;
9295
}
9396

97+
modifier onlySmartnodesToken() {
98+
if (msg.sender != address(i_smartnodesToken))
99+
revert Coordinator__NotTokenContract();
100+
_;
101+
}
102+
94103
modifier onlyEligibleValidator() {
95104
bool isSelectedValidator = _isCurrentRoundValidator(msg.sender);
96105
bool roundExpired = _isCurrentRoundExpired();
@@ -111,6 +120,7 @@ contract SmartnodesCoordinator is ReentrancyGuard {
111120
uint128 _updateTime,
112121
uint8 _requiredApprovalsPercentage,
113122
address _smartnodesCore,
123+
address _smartnodesToken,
114124
address[] memory _genesisNodes
115125
) {
116126
if (
@@ -124,6 +134,7 @@ contract SmartnodesCoordinator is ReentrancyGuard {
124134
}
125135

126136
i_smartnodesCore = ISmartnodesCore(_smartnodesCore);
137+
i_smartnodesToken = ISmartnodesToken(_smartnodesToken);
127138
i_requiredApprovalsPercentage = _requiredApprovalsPercentage;
128139

129140
timeConfig = TimeConfig({
@@ -234,8 +245,8 @@ contract SmartnodesCoordinator is ReentrancyGuard {
234245
uint256 totalCapacity,
235246
address[] calldata validatorsToRemove,
236247
bytes32[] calldata jobHashes,
237-
address[] calldata workers,
238-
uint256[] calldata capacities
248+
bytes32 workersHash,
249+
bytes32 capacitiesHash
239250
) external onlyValidator nonReentrant {
240251
if (proposalId == 0 || proposalId > currentProposals.length) {
241252
revert Coordinator__InvalidProposalNumber();
@@ -262,8 +273,8 @@ contract SmartnodesCoordinator is ReentrancyGuard {
262273
merkleRoot,
263274
validatorsToRemove,
264275
jobHashes,
265-
workers,
266-
capacities
276+
workersHash,
277+
capacitiesHash
267278
);
268279

269280
if (computedHash != storedHash) {
@@ -291,7 +302,8 @@ contract SmartnodesCoordinator is ReentrancyGuard {
291302
jobHashes,
292303
merkleRoot,
293304
totalCapacity,
294-
approvedValidators
305+
approvedValidators,
306+
msg.sender
295307
);
296308
}
297309

@@ -312,15 +324,11 @@ contract SmartnodesCoordinator is ReentrancyGuard {
312324

313325
// ============= ADMIN FUNCTIONS =============
314326
/**
315-
* @notice Half update configuration parameters to allow double to proposal creation times
327+
* @notice Change proposal creation timeframes
316328
*/
317-
function halfStateTime() external onlySmartnodesCore {
318-
TimeConfig memory tc = timeConfig;
319-
uint128 newUpdateTime = tc.updateTime / 2;
320-
if (newUpdateTime == 0) newUpdateTime = 1; // Prevent zero update time
321-
322-
timeConfig.updateTime = newUpdateTime;
323-
emit ConfigUpdated(newUpdateTime);
329+
function updateTiming(uint256 _newInterval) external onlySmartnodesToken {
330+
timeConfig.updateTime = uint128(_newInterval);
331+
emit ConfigUpdated(_newInterval);
324332
}
325333

326334
// ============= INTERNAL FUNCTIONS =============
@@ -419,10 +427,9 @@ contract SmartnodesCoordinator is ReentrancyGuard {
419427
uint256 totalValidators = validators.length;
420428

421429
if (totalValidators < 2) return 1;
422-
if (totalValidators < 4) return 2;
423-
if (totalValidators < 8) return 3;
424-
if (totalValidators < 15) return 4;
425-
return 5; // Max 5 validators for proposal submission
430+
if (totalValidators < 5) return 2;
431+
if (totalValidators < 10) return 3;
432+
return 5;
426433
}
427434

428435
function _cleanupExpiredRound() internal {
@@ -554,8 +561,8 @@ contract SmartnodesCoordinator is ReentrancyGuard {
554561
bytes32 merkleRoot,
555562
address[] calldata validatorsToRemove,
556563
bytes32[] calldata jobHashes,
557-
address[] calldata workers,
558-
uint256[] calldata capacities
564+
bytes32 workersHash,
565+
bytes32 capacitiesHash
559566
) internal pure returns (bytes32) {
560567
return
561568
keccak256(
@@ -564,8 +571,8 @@ contract SmartnodesCoordinator is ReentrancyGuard {
564571
merkleRoot,
565572
validatorsToRemove,
566573
jobHashes,
567-
workers,
568-
capacities
574+
workersHash,
575+
capacitiesHash
569576
)
570577
);
571578
}

src/SmartnodesCore.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ contract SmartnodesCore {
200200
bytes32[] calldata _jobIds,
201201
bytes32 _merkleRoot,
202202
uint256 _totalCapacity,
203-
address[] memory _approvedValidators
203+
address[] memory _approvedValidators,
204+
address _biasValidator
204205
) external onlyCoordinator {
205206
// Get any job payments associated with reward
206207
PaymentAmounts memory additionalRewards = _processCompletedJobs(
@@ -211,7 +212,8 @@ contract SmartnodesCore {
211212
_merkleRoot,
212213
_totalCapacity,
213214
_approvedValidators,
214-
additionalRewards
215+
additionalRewards,
216+
_biasValidator
215217
);
216218
}
217219

src/SmartnodesDAO.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,12 @@ contract SmartnodesDAO is ReentrancyGuard {
200200
if (p.executed) revert SmartnodesDAO__ProposalAlreadyExecuted();
201201
if (p.canceled) revert("proposal canceled");
202202

203-
uint256 quorumVotes = token.totalSupply() / 5; // must have at least 20% of existing holders votes
203+
uint256 quorumVotes = token.totalSupply() / 5 / 1e18; // must have at least 20% of existing holders votes
204+
uint256 forVotesTokenEquivalent = p.forVotes * p.forVotes;
204205

205206
// pass conditions: forVotes > againstVotes && quorum reached
206207
if (p.forVotes <= p.againstVotes) revert("proposal did not pass");
207-
if (p.forVotes < quorumVotes) revert("quorum not reached");
208+
if (forVotesTokenEquivalent < quorumVotes) revert("quorum not reached");
208209

209210
// execute stored calls (revert if any call fails)
210211
uint256 len = p.targets.length;

0 commit comments

Comments
 (0)