建议
// Solve P3
uint256 blockHeightDiff = block.number.sub(stream.lastRewardBlock);
uint256 m = amount.mul(ONE).div(blockHeightDiff); //If underflow m might be 0, peg true kBlock to 1, if bHD 0 then error
uint256 noverk = blockHeightDiff.mul(ONE); // peg true kBlock to 1 so n over k always greater or equal 1
uint256 mu = stream.unlockRatio.mul(ONE).div(1000).div(stream.kBlock); // peg true mu to mu/kBlock
uint256 onesubmu = ONE.sub(mu); // Enlarged due to mu divided by kBlock
// uint256 s = m.mul(ONE.sub(XNum.bpow(onesubmu,noverk))).div(ONE).div(mu).mul(ONE);
uint256 s = m.mul(ONE.sub(XNum.bpow(onesubmu, noverk))).div(mu).div(ONE);
// update remaining and withdrawable balance
stream.lastRewardBlock = block.number;
// Solve P1/P2, keep amount distributed
stream.remaining = remaining.add(s); // = remaining + s
stream.withdrawable = withdrawable.add(amount).sub(s); // = w + amount - s
二测的逻辑是
问题1:r和w其实不需要重新分配,就amount分配给s和剩余 问题2: s是sum,应该给r,剩余给w 问题3: 指数操作其实有边界条件,需要考虑数值精度
建议 // Solve P3 uint256 blockHeightDiff = block.number.sub(stream.lastRewardBlock); uint256 m = amount.mul(ONE).div(blockHeightDiff); //If underflow m might be 0, peg true kBlock to 1, if bHD 0 then error uint256 noverk = blockHeightDiff.mul(ONE); // peg true kBlock to 1 so n over k always greater or equal 1 uint256 mu = stream.unlockRatio.mul(ONE).div(1000).div(stream.kBlock); // peg true mu to mu/kBlock uint256 onesubmu = ONE.sub(mu); // Enlarged due to mu divided by kBlock // uint256 s = m.mul(ONE.sub(XNum.bpow(onesubmu,noverk))).div(ONE).div(mu).mul(ONE); uint256 s = m.mul(ONE.sub(XNum.bpow(onesubmu, noverk))).div(mu).div(ONE);