diff --git a/forum-network/src/classes/forum.js b/forum-network/src/classes/forum.js index cf96b4e..7f1bce1 100644 --- a/forum-network/src/classes/forum.js +++ b/forum-network/src/classes/forum.js @@ -100,7 +100,11 @@ export class Forum extends ReputationHolder { // Apply computed rewards to update values of tokens for (const [id, value] of rewardsAccumulator) { - bench.reputation.transferValueFrom(post.tokenId, id, value); + if (value < 0) { + bench.reputation.transferValueFrom(id, post.tokenId, -value); + } else { + bench.reputation.transferValueFrom(post.tokenId, id, value); + } } // Transfer ownership of the minted/staked token, from the forum to the post author @@ -126,18 +130,31 @@ export class Forum extends ReputationHolder { const citedPostCapacity = citedPost.value / (1 - citedPostTotalCitationWeight); outboundAmount = Math.max(outboundAmount, -citedPostCapacity); } - totalOutboundAmount += outboundAmount; - await this.propagateValue(rewardsAccumulator, post, citedPost, outboundAmount, depth + 1); + const refundFromOutbound = await this.propagateValue( + rewardsAccumulator, + post, + citedPost, + outboundAmount, + depth + 1, + ); + totalOutboundAmount += outboundAmount - refundFromOutbound; } } // Apply leaching value const incrementAfterLeaching = increment - totalOutboundAmount * params.leachingValue; + const rawNewValue = post.value + incrementAfterLeaching; + const newValue = Math.max(0, rawNewValue); + const appliedIncrement = newValue - post.value; + const refundToInbound = increment - appliedIncrement; + // Award reputation to post author - rewardsAccumulator.set(post.tokenId, incrementAfterLeaching); + rewardsAccumulator.set(post.tokenId, appliedIncrement); // Increment the value of the post - await this.setPostValue(post, post.value + incrementAfterLeaching); + await this.setPostValue(post, newValue); + + return refundToInbound; } } diff --git a/forum-network/src/classes/reputation-token.js b/forum-network/src/classes/reputation-token.js index ee93440..e86d33c 100644 --- a/forum-network/src/classes/reputation-token.js +++ b/forum-network/src/classes/reputation-token.js @@ -45,16 +45,17 @@ export class ReputationTokenContract extends ERC721 { if (amount === undefined) { throw new Error('Transfer value: amount is undefined!'); } + if (amount === 0) { + return; + } + if (amount < 0) { + throw new Error('Transfer value: amount must be positive'); + } const sourceAvailable = this.availableValueOf(fromTokenId); - const targetAvailable = this.availableValueOf(toTokenId); if (sourceAvailable < amount - EPSILON) { throw new Error('Token value transfer: source has insufficient available value. ' + `Needs ${amount}; has ${sourceAvailable}.`); } - if (targetAvailable < -amount + EPSILON) { - throw new Error('Token value transfer: target has insufficient available value. ' - + `Needs ${-amount}; has ${targetAvailable}.`); - } this.incrementValue(fromTokenId, -amount); this.incrementValue(toTokenId, amount); }