Fixup negative citation propagations to handle all cases

This commit is contained in:
Ladd Hoffman 2023-01-28 09:37:46 -06:00
parent 667a051c13
commit d1570e7672
2 changed files with 28 additions and 10 deletions

View File

@ -100,8 +100,12 @@ export class Forum extends ReputationHolder {
// Apply computed rewards to update values of tokens // Apply computed rewards to update values of tokens
for (const [id, value] of rewardsAccumulator) { for (const [id, value] of rewardsAccumulator) {
if (value < 0) {
bench.reputation.transferValueFrom(id, post.tokenId, -value);
} else {
bench.reputation.transferValueFrom(post.tokenId, id, value); bench.reputation.transferValueFrom(post.tokenId, id, value);
} }
}
// Transfer ownership of the minted/staked token, from the forum to the post author // Transfer ownership of the minted/staked token, from the forum to the post author
bench.reputation.transferFrom(this.id, post.authorPublicKey, post.tokenId); bench.reputation.transferFrom(this.id, post.authorPublicKey, post.tokenId);
@ -126,18 +130,31 @@ export class Forum extends ReputationHolder {
const citedPostCapacity = citedPost.value / (1 - citedPostTotalCitationWeight); const citedPostCapacity = citedPost.value / (1 - citedPostTotalCitationWeight);
outboundAmount = Math.max(outboundAmount, -citedPostCapacity); outboundAmount = Math.max(outboundAmount, -citedPostCapacity);
} }
totalOutboundAmount += outboundAmount; const refundFromOutbound = await this.propagateValue(
await this.propagateValue(rewardsAccumulator, post, citedPost, outboundAmount, depth + 1); rewardsAccumulator,
post,
citedPost,
outboundAmount,
depth + 1,
);
totalOutboundAmount += outboundAmount - refundFromOutbound;
} }
} }
// Apply leaching value // Apply leaching value
const incrementAfterLeaching = increment - totalOutboundAmount * params.leachingValue; 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 // Award reputation to post author
rewardsAccumulator.set(post.tokenId, incrementAfterLeaching); rewardsAccumulator.set(post.tokenId, appliedIncrement);
// Increment the value of the post // Increment the value of the post
await this.setPostValue(post, post.value + incrementAfterLeaching); await this.setPostValue(post, newValue);
return refundToInbound;
} }
} }

View File

@ -45,16 +45,17 @@ export class ReputationTokenContract extends ERC721 {
if (amount === undefined) { if (amount === undefined) {
throw new Error('Transfer value: amount is 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 sourceAvailable = this.availableValueOf(fromTokenId);
const targetAvailable = this.availableValueOf(toTokenId);
if (sourceAvailable < amount - EPSILON) { if (sourceAvailable < amount - EPSILON) {
throw new Error('Token value transfer: source has insufficient available value. ' throw new Error('Token value transfer: source has insufficient available value. '
+ `Needs ${amount}; has ${sourceAvailable}.`); + `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(fromTokenId, -amount);
this.incrementValue(toTokenId, amount); this.incrementValue(toTokenId, amount);
} }