Skip to content

Commit

Permalink
remove hardcoding of TREE_ARITY as its value can change between MACI …
Browse files Browse the repository at this point in the history
…versions
  • Loading branch information
yuetloo committed May 22, 2024
1 parent 465a116 commit f9d90ab
Show file tree
Hide file tree
Showing 25 changed files with 531 additions and 273 deletions.
32 changes: 13 additions & 19 deletions contracts/contracts/ClrFund.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params {
error InvalidFundingRoundFactory();
error InvalidMaciFactory();
error RecipientRegistryNotSet();
error MaxRecipientsNotSet();
error NotInitialized();
error VoteOptionTreeDepthNotSet();


/**
Expand Down Expand Up @@ -128,20 +128,6 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params {
_setFundingRoundFactory(_roundFactory);
}

/**
* @dev Get the maximum recipients allowed in the recipient registry
*/
function getMaxRecipients() public view returns (uint256 _maxRecipients) {
TreeDepths memory treeDepths = maciFactory.treeDepths();
if (treeDepths.voteOptionTreeDepth == 0) revert VoteOptionTreeDepthNotSet();

uint256 maxVoteOption = maciFactory.TREE_ARITY() ** treeDepths.voteOptionTreeDepth;

// -1 because the first slot of the recipients array is not used
// and maxRecipients is used to generate 0 based index to the array
_maxRecipients = maxVoteOption - 1;
}

/**
* @dev Set registry of verified users.
* @param _userRegistry Address of a user registry.
Expand All @@ -155,6 +141,15 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params {
emit UserRegistryChanged(address(_userRegistry));
}

/**
* @dev Set the max recipients in the recipient registry
*/
function _setMaxRecipients() private {
if (address(maciFactory) == address(0)) revert NotInitialized();
if (maciFactory.maxRecipients() == 0) revert MaxRecipientsNotSet();
recipientRegistry.setMaxRecipients(maciFactory.maxRecipients());
}

/**
* @dev Set recipient registry.
* @param _recipientRegistry Address of a recipient registry.
Expand All @@ -163,9 +158,9 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params {
external
onlyOwner
{

recipientRegistry = _recipientRegistry;
uint256 maxRecipients = getMaxRecipients();
recipientRegistry.setMaxRecipients(maxRecipients);
_setMaxRecipients();

emit RecipientRegistryChanged(address(_recipientRegistry));
}
Expand Down Expand Up @@ -229,8 +224,7 @@ contract ClrFund is OwnableUpgradeable, DomainObjs, Params {
if (address(recipientRegistry) == address(0)) revert RecipientRegistryNotSet();

// Make sure that the max number of recipients is set correctly
uint256 maxRecipients = getMaxRecipients();
recipientRegistry.setMaxRecipients(maxRecipients);
_setMaxRecipients();

// Deploy funding round and MACI contracts
address newRound = roundFactory.deploy(duration, address(this));
Expand Down
33 changes: 13 additions & 20 deletions contracts/contracts/FundingRound.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ contract FundingRound is
error TallyHashNotPublished();
error IncompleteTallyResults(uint256 total, uint256 actual);
error NoVotes();
error NoSignUps();
error MaciNotSet();
error PollNotSet();
error InvalidMaci();
Expand Down Expand Up @@ -175,19 +176,6 @@ contract FundingRound is
return (addressValue == address(0));
}

/**
* @dev Have the votes been tallied
*/
function isTallied() private view returns (bool) {
(uint256 numSignUps, ) = poll.numSignUpsAndMessages();
(uint8 intStateTreeDepth, , , ) = poll.treeDepths();
uint256 tallyBatchSize = TREE_ARITY ** uint256(intStateTreeDepth);
uint256 tallyBatchNum = tally.tallyBatchNum();
uint256 totalTallied = tallyBatchNum * tallyBatchSize;

return numSignUps > 0 && totalTallied >= numSignUps;
}

/**
* @dev Set the tally contract
* @param _tally The tally contract address
Expand Down Expand Up @@ -470,18 +458,18 @@ contract FundingRound is

_votingPeriodOver(poll);

if (!isTallied()) {
if (!tally.isTallied()) {
revert VotesNotTallied();
}

if (bytes(tallyHash).length == 0) {
revert TallyHashNotPublished();
}

// make sure we have received all the tally results
(,,, uint8 voteOptionTreeDepth) = poll.treeDepths();
uint256 totalResults = uint256(TREE_ARITY) ** uint256(voteOptionTreeDepth);
if ( totalTallyResults != totalResults ) {
revert IncompleteTallyResults(totalResults, totalTallyResults);
(, uint256 maxVoteOptions) = poll.maxValues();
if (totalTallyResults != maxVoteOptions) {
revert IncompleteTallyResults(maxVoteOptions, totalTallyResults);
}

// If nobody voted, the round should be cancelled to avoid locking of matching funds
Expand All @@ -494,7 +482,6 @@ contract FundingRound is
revert IncorrectSpentVoiceCredits();
}


totalSpent = _totalSpent;
// Total amount of spent voice credits is the size of the pool of direct rewards.
// Everything else, including unspent voice credits and downscaling error,
Expand Down Expand Up @@ -675,9 +662,15 @@ contract FundingRound is
{
if (isAddressZero(address(maci))) revert MaciNotSet();

if (!isTallied()) {
if (maci.numSignUps() == 0) {
// no sign ups, so no tally results
revert NoSignUps();
}

if (!tally.isTallied()) {
revert VotesNotTallied();
}

if (isFinalized) {
revert RoundAlreadyFinalized();
}
Expand Down
3 changes: 0 additions & 3 deletions contracts/contracts/MACICommon.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ pragma solidity 0.8.20;
* @dev a contract that holds common MACI structures
*/
contract MACICommon {
// MACI tree arity
uint256 public constant TREE_ARITY = 5;

/**
* @dev These are contract factories used to deploy MACI poll processing contracts
* when creating a new ClrFund funding round.
Expand Down
25 changes: 14 additions & 11 deletions contracts/contracts/MACIFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA
// circuit parameters
uint8 public stateTreeDepth;
TreeDepths public treeDepths;
uint256 public messageBatchSize;
uint256 public maxRecipients;

// Events
event MaciParametersChanged();
Expand All @@ -38,11 +40,15 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA
error NotInitialized();
error ProcessVkNotSet();
error TallyVkNotSet();
error VoteOptionTreeDepthNotSet();
error InvalidVkRegistry();
error InvalidPollFactory();
error InvalidTallyFactory();
error InvalidMessageProcessorFactory();
error InvalidVerifier();
error InvalidMaxRecipients();
error InvalidMessageBatchSize();
error InvalidVoteOptionTreeDepth();

constructor(
address _vkRegistry,
Expand All @@ -60,14 +66,6 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA
verifier = Verifier(_verifier);
}

/**
* @dev calculate the message batch size
*/
function getMessageBatchSize(uint8 messageTreeSubDepth) public pure
returns(uint256 _messageBatchSize) {
_messageBatchSize = TREE_ARITY ** messageTreeSubDepth;
}

/**
* @dev set vk registry
*/
Expand Down Expand Up @@ -122,13 +120,19 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA
*/
function setMaciParameters(
uint8 _stateTreeDepth,
uint256 _messageBatchSize,
uint256 _maxRecipients,
TreeDepths calldata _treeDepths
)
public
onlyOwner
{
if (_treeDepths.voteOptionTreeDepth == 0) revert InvalidVoteOptionTreeDepth();
if (_maxRecipients == 0) revert InvalidMaxRecipients();
if (_messageBatchSize == 0) revert InvalidMessageBatchSize();

uint256 messageBatchSize = getMessageBatchSize(_treeDepths.messageTreeSubDepth);
messageBatchSize = _messageBatchSize;
maxRecipients = _maxRecipients;

if (!vkRegistry.hasProcessVk(
_stateTreeDepth,
Expand All @@ -155,6 +159,7 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA
emit MaciParametersChanged();
}


/**
* @dev Deploy new MACI instance.
*/
Expand All @@ -170,8 +175,6 @@ contract MACIFactory is Ownable(msg.sender), Params, SnarkCommon, DomainObjs, MA
external
returns (MACI _maci, MACI.PollContracts memory _pollContracts)
{
uint256 messageBatchSize = getMessageBatchSize(treeDepths.messageTreeSubDepth);

if (!vkRegistry.hasProcessVk(
stateTreeDepth,
treeDepths.messageTreeDepth,
Expand Down
5 changes: 1 addition & 4 deletions contracts/contracts/interfaces/IMACIFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ interface IMACIFactory {
function stateTreeDepth() external view returns (uint8);
function treeDepths() external view returns (Params.TreeDepths memory);

function getMessageBatchSize(uint8 _messageTreeSubDepth) external pure
returns(uint256 _messageBatchSize);

function TREE_ARITY() external pure returns (uint256);
function maxRecipients() external view returns (uint256);

function deployMaci(
SignUpGatekeeper signUpGatekeeper,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pragma solidity 0.8.20;
*/
interface IRecipientRegistry {

function maxRecipients() external returns (uint256);
function setMaxRecipients(uint256 _maxRecipients) external returns (bool);

function getRecipientAddress(uint256 _index, uint256 _startBlock, uint256 _endBlock) external view returns (address);
Expand Down
1 change: 1 addition & 0 deletions contracts/tasks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ import './runners/proveOnChain'
import './runners/publishTallyResults'
import './runners/resetTally'
import './runners/maciPubkey'
import './runners/simulateContribute'
Loading

0 comments on commit f9d90ab

Please sign in to comment.