@@ -129,6 +129,7 @@ contract ResultsRewards {
129129 address _solver ,
130130 bool _isCorrect ,
131131 uint256 _score ,
132+ uint256 _alignmentScore ,
132133 string calldata _reportCid
133134 ) external onlyStakedCoordinator {
134135 AutonetLib.TaskProposal memory proposal = taskContract.getTaskProposal (_taskId);
@@ -159,6 +160,7 @@ contract ResultsRewards {
159160 coordinator: msg .sender ,
160161 isCorrect: _isCorrect,
161162 score: _score,
163+ alignmentScore: _alignmentScore,
162164 stake: stakeInfo.amount,
163165 voteBlock: block .number ,
164166 reportHash: keccak256 (abi.encodePacked (_reportCid))
@@ -187,14 +189,15 @@ contract ResultsRewards {
187189 require (taskVotes.length >= MIN_COORDINATORS, "Insufficient coordinator votes " );
188190
189191 // Compute Yuma consensus
190- (bool consensusCorrect , uint256 consensusScore , uint256 totalStake , uint256 correctStake , uint256 clippedCount ) =
192+ (bool consensusCorrect , uint256 consensusScore , uint256 consensusAlignmentScore , uint256 totalStake , uint256 correctStake , uint256 clippedCount ) =
191193 _computeYumaConsensus (_taskId, taskVotes);
192194
193195 // Store result
194196 result.taskId = _taskId;
195197 result.solver = _solver;
196198 result.consensusCorrect = consensusCorrect;
197199 result.consensusScore = consensusScore;
200+ result.consensusAlignmentScore = consensusAlignmentScore;
198201 result.totalStake = totalStake;
199202 result.correctStake = correctStake;
200203 result.clippedVotes = clippedCount;
@@ -212,35 +215,40 @@ contract ResultsRewards {
212215 emit YumaConsensusReached (_taskId, _solver, consensusCorrect, consensusScore);
213216
214217 // Process rewards
215- _processRewardsYuma (_taskId, _solver, taskVotes, consensusCorrect, consensusScore);
218+ _processRewardsYuma (_taskId, _solver, taskVotes, consensusCorrect, consensusScore, consensusAlignmentScore );
216219 }
217220
218221 /**
219222 * @dev Compute Yuma consensus with stake-weighted voting and clipping.
220223 */
221224 function _computeYumaConsensus (uint256 _taskId , AutonetLib.CoordinatorVote[] storage taskVotes )
222225 internal
223- returns (bool consensusCorrect , uint256 consensusScore , uint256 totalStake , uint256 correctStake , uint256 clippedCount )
226+ returns (bool consensusCorrect , uint256 consensusScore , uint256 consensusAlignmentScore , uint256 totalStake , uint256 correctStake , uint256 clippedCount )
224227 {
225228 uint256 numVotes = taskVotes.length ;
226229
227- // Calculate total stake and stake-weighted score
230+ // Calculate total stake, stake-weighted correctness score, and alignment score
228231 uint256 weightedScoreSum = 0 ;
232+ uint256 weightedAlignmentSum = 0 ;
229233 for (uint256 i = 0 ; i < numVotes; i++ ) {
230234 totalStake += taskVotes[i].stake;
231235 if (taskVotes[i].isCorrect) {
232236 correctStake += taskVotes[i].stake;
233237 }
234238 weightedScoreSum += taskVotes[i].score * taskVotes[i].stake;
239+ weightedAlignmentSum += taskVotes[i].alignmentScore * taskVotes[i].stake;
235240 }
236241
237242 // Consensus correct if majority stake agrees
238243 consensusCorrect = correctStake > totalStake / 2 ;
239244
240- // Calculate stake-weighted average score (before clipping)
245+ // Stake-weighted average alignment score (no clipping — alignment is subjective)
246+ consensusAlignmentScore = totalStake > 0 ? weightedAlignmentSum / totalStake : 0 ;
247+
248+ // Calculate stake-weighted average correctness score (before clipping)
241249 uint256 avgScore = totalStake > 0 ? weightedScoreSum / totalStake : 0 ;
242250
243- // Apply clipping: scores that deviate too much from average are clipped
251+ // Apply clipping: correctness scores that deviate too much from average are clipped
244252 uint256 clippedWeightedSum = 0 ;
245253 uint256 clippedTotalStake = 0 ;
246254
@@ -306,7 +314,8 @@ contract ResultsRewards {
306314 address _solver ,
307315 AutonetLib.CoordinatorVote[] storage taskVotes ,
308316 bool _isCorrect ,
309- uint256 _consensusScore
317+ uint256 _consensusScore ,
318+ uint256 _consensusAlignmentScore
310319 ) internal {
311320 require (! rewardsProcessed[_taskId], "Already processed " );
312321
@@ -340,8 +349,11 @@ contract ResultsRewards {
340349 }
341350
342351 if (_isCorrect) {
343- // Solver reward scaled by consensus score
344- uint256 scaledSolverReward = (proposal.proposedSolverReward * _consensusScore) / 100 ;
352+ // Solver reward scaled by correctness AND alignment
353+ // correctness: 0-100, alignment: 0-10000 (basis points)
354+ // Formula: base * (correctness/100) * (alignment/10000)
355+ // = base * correctness * alignment / 1_000_000
356+ uint256 scaledSolverReward = (proposal.proposedSolverReward * _consensusScore * _consensusAlignmentScore) / 1000000 ;
345357 try rpbContract.disburseFromBudget (_solver, scaledSolverReward) returns (bool success ) {
346358 if (success) {
347359 emit RewardsDistributed (_taskId, _solver, scaledSolverReward, "SolverReward " );
@@ -350,7 +362,7 @@ contract ResultsRewards {
350362 // Continue if disbursement fails
351363 }
352364
353- // Proposer reward
365+ // Proposer reward (not alignment-gated — proposers create tasks, not charters)
354366 try rpbContract.disburseFromBudget (proposal.proposer, proposal.proposedLearnabilityReward) returns (bool success ) {
355367 if (success) {
356368 emit RewardsDistributed (_taskId, proposal.proposer, proposal.proposedLearnabilityReward, "ProposerReward " );
@@ -539,6 +551,7 @@ contract ResultsRewards {
539551 address _solver ,
540552 bool _isCorrect ,
541553 uint256 _score ,
554+ uint256 _alignmentScore ,
542555 string calldata _reportCid
543556 ) external onlyStakedCoordinator {
544557 AutonetLib.TaskProposal memory proposal = taskContract.getTaskProposal (_taskId);
0 commit comments