原为(建议注释,方便审计判断功能统一,仅数学简化)
//If remaining not equal zero, it means there have been added funds.
uint256 r = stream.remaining;
uint256 w = 0;
uint256 n = block.number.sub(stream.lastRewardBlock).div(stream.kBlock);
for (uint256 i = 0; i < n; i++) {
uint256 reward = r.mul(stream.unlockRatio).div(1000);
w = w.add(reward);
r = r.sub(reward);
if (r < effectiveValues[streamId]) {
break;
}
}
改进:把循环简化到乘方
uint256 n = block.number.sub(stream.lastRewardBlock).div(stream.kBlock);
uint256 k = stream.unlockRatio.div(1000); // k=0.001 For Standard HalfLife
uint256 mu = 1.sub(k); // mu=0.999 For Standard HalfLife
uint256 r = stream.remaining.mul(mu.pow(n)); // Same Result With Commented Lines
uint256 w = stream.remaining.sub(r); // withdrawable, if n is float this process will be smooth, slightly higher gas
更进一步的,因为BalanceOf简化了,因此k=[0.0000167, 0.00000185,0.000000555,0.000000278] while kBlock==1
corresponding to kBlock=[60,540,1800,3600] when k=0.001
可以用Python参考校验
···
def compute1(k,r,n):
w = 0
rr = r
for i in range(np.int(n)):
reward = rr * k
w = w + reward
rr = rr - reward
return (w,rr)
def compute2(k,r,n):
rr = r * ((1 - k)**np.int(n))
w = r - rr
return (w,rr)
for i in range(20):
n = np.random.randint(100)
k = np.random.uniform(0,1)
r = np.random.exponential()
print(n,k,r,compute1(k,r,n))
print(n,k,r,compute2(k,r,n))
···
原为(建议注释,方便审计判断功能统一,仅数学简化) //If
remaining
not equal zero, it means there have been added funds. uint256 r = stream.remaining; uint256 w = 0; uint256 n = block.number.sub(stream.lastRewardBlock).div(stream.kBlock); for (uint256 i = 0; i < n; i++) { uint256 reward = r.mul(stream.unlockRatio).div(1000); w = w.add(reward); r = r.sub(reward); if (r < effectiveValues[streamId]) { break; } }改进:把循环简化到乘方
可以用Python参考校验 ··· def compute1(k,r,n): w = 0 rr = r for i in range(np.int(n)): reward = rr * k w = w + reward rr = rr - reward return (w,rr)
def compute2(k,r,n): rr = r * ((1 - k)**np.int(n)) w = r - rr return (w,rr)
for i in range(20): n = np.random.randint(100) k = np.random.uniform(0,1) r = np.random.exponential() print(n,k,r,compute1(k,r,n)) print(n,k,r,compute2(k,r,n)) ···