Implement Curyo 2 question reward pools foundation#126
Draft
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Comment on lines
+1184
to
+1186
| function _voterIdForRound(uint256 contentId, uint256 roundId, address account) internal view returns (uint256) { | ||
| return _roundVoterIdNft(contentId, roundId).getTokenId(account); | ||
| } |
Comment on lines
+1184
to
+1186
| function _voterIdForRound(uint256 contentId, uint256 roundId, address account) internal view returns (uint256) { | ||
| return _roundVoterIdNft(contentId, roundId).getTokenId(account); | ||
| } |
Comment on lines
+748
to
+756
| returns (uint256 resolvedCategoryId) | ||
| { | ||
| require(metadata.categoryId != 0, "Category required"); | ||
| require(categoryRegistry.isCategory(metadata.categoryId), "Category not registered"); | ||
| return metadata.categoryId; | ||
| } | ||
|
|
||
| function _deriveQuestionMediaSubmissionKey(SubmissionMetadata memory metadata, uint256 resolvedCategoryId) | ||
| internal |
Comment on lines
+630
to
+646
| function _validatedContextSubmissionMetadata( | ||
| string memory contextUrl, | ||
| string[] memory imageUrls, | ||
| string memory videoUrl, | ||
| string memory title, | ||
| string memory description, | ||
| string memory tags, | ||
| uint256 categoryId | ||
| ) internal view returns (SubmissionMetadata memory metadata) { | ||
| SUBMISSION_MEDIA_VALIDATOR.validateContextUrl(contextUrl); | ||
| SUBMISSION_MEDIA_VALIDATOR.validateOptionalMediaSet(imageUrls, videoUrl); | ||
| metadata = SubmissionMetadata({ | ||
| url: contextUrl, title: title, description: description, tags: tags, categoryId: categoryId | ||
| }); | ||
| _validateTextFields(metadata); | ||
| require(address(categoryRegistry) != address(0), "CategoryRegistry not set"); | ||
| } |
Comment on lines
+630
to
+646
| function _validatedContextSubmissionMetadata( | ||
| string memory contextUrl, | ||
| string[] memory imageUrls, | ||
| string memory videoUrl, | ||
| string memory title, | ||
| string memory description, | ||
| string memory tags, | ||
| uint256 categoryId | ||
| ) internal view returns (SubmissionMetadata memory metadata) { | ||
| SUBMISSION_MEDIA_VALIDATOR.validateContextUrl(contextUrl); | ||
| SUBMISSION_MEDIA_VALIDATOR.validateOptionalMediaSet(imageUrls, videoUrl); | ||
| metadata = SubmissionMetadata({ | ||
| url: contextUrl, title: title, description: description, tags: tags, categoryId: categoryId | ||
| }); | ||
| _validateTextFields(metadata); | ||
| require(address(categoryRegistry) != address(0), "CategoryRegistry not set"); | ||
| } |
Comment on lines
+783
to
+806
| function _requireCompletedBundle(uint256 bundleId, uint256 voterId) | ||
| internal | ||
| view | ||
| returns (address frontend, bytes32 firstCommitKey) | ||
| { | ||
| BundleQuestion[] storage questions = bundleQuestions[bundleId]; | ||
| require(questions.length > 0, "No questions"); | ||
| for (uint256 i = 0; i < questions.length; i++) { | ||
| BundleQuestion storage question = questions[i]; | ||
| require(question.terminal && question.settled, "Question not settled"); | ||
| bytes32 commitKey = votingEngine.voterIdCommitKey(question.contentId, question.roundId, voterId); | ||
| require(commitKey != bytes32(0), "No commit"); | ||
| require( | ||
| votingEngine.commitVoterId(question.contentId, question.roundId, commitKey) == voterId, "Wrong Voter ID" | ||
| ); | ||
| (bool revealed, address questionFrontend) = | ||
| _revealedCommitFrontend(question.contentId, question.roundId, commitKey); | ||
| require(revealed, "Vote not revealed"); | ||
| if (i == 0) { | ||
| frontend = questionFrontend; | ||
| firstCommitKey = commitKey; | ||
| } | ||
| } | ||
| } |
Comment on lines
+808
to
+820
| function _hasCompletedBundle(uint256 bundleId, uint256 voterId) internal view returns (bool) { | ||
| BundleQuestion[] storage questions = bundleQuestions[bundleId]; | ||
| if (questions.length == 0) return false; | ||
| for (uint256 i = 0; i < questions.length; i++) { | ||
| BundleQuestion storage question = questions[i]; | ||
| if (!question.terminal || !question.settled) return false; | ||
| bytes32 commitKey = votingEngine.voterIdCommitKey(question.contentId, question.roundId, voterId); | ||
| if (commitKey == bytes32(0)) return false; | ||
| (bool revealed,) = _revealedCommitFrontend(question.contentId, question.roundId, commitKey); | ||
| if (!revealed) return false; | ||
| } | ||
| return true; | ||
| } |
Comment on lines
+822
to
+840
| function _isBundleExcludedVoter(BundleReward storage bundle, uint256 bundleId, uint256 voterId) | ||
| internal | ||
| view | ||
| returns (bool) | ||
| { | ||
| BundleQuestion[] storage questions = bundleQuestions[bundleId]; | ||
| for (uint256 i = 0; i < questions.length; i++) { | ||
| BundleQuestion storage question = questions[i]; | ||
| uint256 funderVoterId = _funderVoterIdForBundleQuestion(bundle, question.contentId, question.roundId); | ||
| if (voterId == funderVoterId) return true; | ||
|
|
||
| address submitterIdentity = registry.getSubmitterIdentity(question.contentId); | ||
| if (submitterIdentity != address(0)) { | ||
| uint256 submitterVoterId = _voterIdForRound(question.contentId, question.roundId, submitterIdentity); | ||
| if (voterId == submitterVoterId) return true; | ||
| } | ||
| } | ||
| return false; | ||
| } |
Comment on lines
+822
to
+840
| function _isBundleExcludedVoter(BundleReward storage bundle, uint256 bundleId, uint256 voterId) | ||
| internal | ||
| view | ||
| returns (bool) | ||
| { | ||
| BundleQuestion[] storage questions = bundleQuestions[bundleId]; | ||
| for (uint256 i = 0; i < questions.length; i++) { | ||
| BundleQuestion storage question = questions[i]; | ||
| uint256 funderVoterId = _funderVoterIdForBundleQuestion(bundle, question.contentId, question.roundId); | ||
| if (voterId == funderVoterId) return true; | ||
|
|
||
| address submitterIdentity = registry.getSubmitterIdentity(question.contentId); | ||
| if (submitterIdentity != address(0)) { | ||
| uint256 submitterVoterId = _voterIdForRound(question.contentId, question.roundId, submitterIdentity); | ||
| if (voterId == submitterVoterId) return true; | ||
| } | ||
| } | ||
| return false; | ||
| } |
Comment on lines
+1024
to
+1032
| function _revealedCommitFrontend(uint256 contentId, uint256 roundId, bytes32 commitKey) | ||
| internal | ||
| view | ||
| returns (bool revealed, address frontend) | ||
| { | ||
| (address voter,,,,, address commitFrontend,, bool commitRevealed,,) = | ||
| votingEngine.commits(contentId, roundId, commitKey); | ||
| return (voter != address(0) && commitRevealed, commitFrontend); | ||
| } |
Comment on lines
+1047
to
+1049
| mstore(add(add(encoded, 32), offset), value) | ||
| } | ||
| } |
Comment on lines
+411
to
+515
| function submitQuestionBundleWithRewardAndRoundConfig( | ||
| BundleQuestionInput[] calldata questions, | ||
| SubmissionRewardTerms calldata rewardTerms, | ||
| RoundLib.RoundConfig calldata roundConfig | ||
| ) external nonReentrant whenNotPaused returns (uint256 bundleId, uint256[] memory contentIds) { | ||
| require(questions.length > 0, "No questions"); | ||
| require(questions.length <= MAX_QUESTION_BUNDLE_COUNT, "Too many questions"); | ||
| require(questionRewardPoolEscrow != address(0), "Bounty escrow not set"); | ||
|
|
||
| RoundLib.RoundConfig memory validatedRoundConfig = _validatedRoundConfig(roundConfig); | ||
| _validateSubmissionReward(rewardTerms); | ||
|
|
||
| SubmissionMetadata[] memory metadataList = new SubmissionMetadata[](questions.length); | ||
| bytes32[] memory submissionKeys = new bytes32[](questions.length); | ||
| bytes32[] memory mediaHashes = new bytes32[](questions.length); | ||
| uint256[] memory resolvedCategoryIds = new uint256[](questions.length); | ||
|
|
||
| for (uint256 i = 0; i < questions.length; i++) { | ||
| BundleQuestionInput calldata question = questions[i]; | ||
| SubmissionMetadata memory metadata = _validatedContextSubmissionMetadata( | ||
| question.contextUrl, | ||
| question.imageUrls, | ||
| question.videoUrl, | ||
| question.title, | ||
| question.description, | ||
| question.tags, | ||
| question.categoryId | ||
| ); | ||
| uint256 resolvedCategoryId = _resolveQuestionSubmissionCategory(metadata); | ||
| bytes32 submissionKey = _deriveQuestionMediaSubmissionKey(metadata, resolvedCategoryId); | ||
| require(!submissionKeyUsed[submissionKey], "Question already submitted"); | ||
|
|
||
| metadataList[i] = metadata; | ||
| submissionKeys[i] = submissionKey; | ||
| mediaHashes[i] = _submissionMediaHash(question.imageUrls, question.videoUrl); | ||
| resolvedCategoryIds[i] = resolvedCategoryId; | ||
| } | ||
|
|
||
| bytes32 bundleHash = _computeQuestionBundleHash(metadataList, mediaHashes, resolvedCategoryIds, questions); | ||
| bytes32 revealCommitment = | ||
| _computeBundleRevealCommitment(bundleHash, msg.sender, rewardTerms, validatedRoundConfig); | ||
| PendingSubmission memory pending = pendingSubmissions[revealCommitment]; | ||
| require(pending.submitter == msg.sender, "Reservation not found"); | ||
| require(block.timestamp <= pending.expiresAt, "Reservation expired"); | ||
| require(block.timestamp >= pending.reservedAt + RESERVED_SUBMISSION_MIN_AGE, "Reservation too new"); | ||
| delete pendingSubmissions[revealCommitment]; | ||
|
|
||
| bundleId = nextQuestionBundleId++; | ||
| contentIds = new uint256[](questions.length); | ||
| for (uint256 i = 0; i < questions.length; i++) { | ||
| submissionKeyUsed[submissionKeys[i]] = true; | ||
| bytes32 contentHash = keccak256( | ||
| abi.encode( | ||
| "curyo-question-context-v1", | ||
| metadataList[i].url, | ||
| questions[i].imageUrls, | ||
| questions[i].videoUrl, | ||
| metadataList[i].title, | ||
| metadataList[i].description, | ||
| metadataList[i].tags, | ||
| resolvedCategoryIds[i] | ||
| ) | ||
| ); | ||
| uint256 contentId = _storeSubmittedContent( | ||
| submissionKeys[i], pending, contentHash, resolvedCategoryIds[i], validatedRoundConfig, bundleId, i | ||
| ); | ||
| contentIds[i] = contentId; | ||
| questionBundleContentIds[bundleId].push(contentId); | ||
|
|
||
| emit ContentSubmitted( | ||
| contentId, | ||
| msg.sender, | ||
| contentHash, | ||
| metadataList[i].url, | ||
| metadataList[i].title, | ||
| metadataList[i].description, | ||
| metadataList[i].tags, | ||
| resolvedCategoryIds[i] | ||
| ); | ||
| emit ContentMediaSubmitted(contentId, questions[i].imageUrls, questions[i].videoUrl); | ||
| emit QuestionBundleContentLinked(bundleId, contentId, i); | ||
| } | ||
|
|
||
| uint256 rewardPoolId = IQuestionRewardPoolEscrow(questionRewardPoolEscrow) | ||
| .createSubmissionBundleFromRegistry( | ||
| bundleId, | ||
| contentIds, | ||
| msg.sender, | ||
| rewardTerms.asset, | ||
| rewardTerms.amount, | ||
| rewardTerms.requiredVoters, | ||
| rewardTerms.expiresAt | ||
| ); | ||
| emit QuestionBundleSubmitted( | ||
| bundleId, | ||
| msg.sender, | ||
| questions.length, | ||
| rewardTerms.asset, | ||
| rewardTerms.amount, | ||
| rewardTerms.requiredVoters, | ||
| rewardTerms.expiresAt, | ||
| bundleHash, | ||
| rewardPoolId | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Verification
Notes