From e25ede414039f603480173bbcd1953ec2476973c Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Mon, 30 Sep 2024 18:36:55 +0200 Subject: [PATCH 1/2] (Circles): correct issuance function for calculating exactly on a completed hour --- src/circles/Circles.sol | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/circles/Circles.sol b/src/circles/Circles.sol index 45d2c63..396bbfb 100644 --- a/src/circles/Circles.sol +++ b/src/circles/Circles.sol @@ -113,9 +113,20 @@ contract Circles is ERC1155, ICirclesErrors { int128 k = Math64x64.fromUInt((startMint - (dA * 1 days + inflationDayZero)) / 1 hours); // Calculate the number of incompleted hours remaining in day B from current timestamp - int128 l = Math64x64.fromUInt(((dB + 1) * 1 days + inflationDayZero - block.timestamp) / 1 hours + 1); + int128 l; + uint256 secondsRemainingInB = ((dB + 1) * 1 days + inflationDayZero - block.timestamp); + if ((secondsRemainingInB % 1 hours) == 0) { + // to count the incompleted hours remaining in day B, when claiming issuance on exactly a full hour, + // we can simply take the integer division, as the preceding hour has just completed. + l = Math64x64.fromUInt(secondsRemainingInB / 1 hours); + } else { + // however, most often the issuance is not on the rounded hour exactly, so the current hour has not yet + // completed and we should not yet issue it (and substract an extra hour for the current hour) + l = Math64x64.fromUInt((secondsRemainingInB / 1 hours) + 1); + } // calculate the overcounted (demurraged) k (in day A) and l (in day B) hours + // note that the hours l are not demurraged as it is current day by construction int128 overcount = Math64x64.add(Math64x64.mul(R[n], k), l); // subtract the overcount from the total issuance, and convert to attoCircles From f8a5e08d09aa65471c939496c72856a524493d05 Mon Sep 17 00:00:00 2001 From: Benjamin Bollen Date: Tue, 1 Oct 2024 21:31:55 +0100 Subject: [PATCH 2/2] (circles): improve the impl so save compile size and improve readability --- src/circles/Circles.sol | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/circles/Circles.sol b/src/circles/Circles.sol index 396bbfb..971f6bf 100644 --- a/src/circles/Circles.sol +++ b/src/circles/Circles.sol @@ -112,18 +112,14 @@ contract Circles is ERC1155, ICirclesErrors { // calculate the number of completed hours in day A until `startMint` int128 k = Math64x64.fromUInt((startMint - (dA * 1 days + inflationDayZero)) / 1 hours); - // Calculate the number of incompleted hours remaining in day B from current timestamp - int128 l; + // Calculate the number of seconds remaining in the current day (dB) uint256 secondsRemainingInB = ((dB + 1) * 1 days + inflationDayZero - block.timestamp); - if ((secondsRemainingInB % 1 hours) == 0) { - // to count the incompleted hours remaining in day B, when claiming issuance on exactly a full hour, - // we can simply take the integer division, as the preceding hour has just completed. - l = Math64x64.fromUInt(secondsRemainingInB / 1 hours); - } else { - // however, most often the issuance is not on the rounded hour exactly, so the current hour has not yet - // completed and we should not yet issue it (and substract an extra hour for the current hour) - l = Math64x64.fromUInt((secondsRemainingInB / 1 hours) + 1); - } + // Calculate the number of complete hours remaining + uint256 hoursRemainingInB = secondsRemainingInB / 1 hours; + // Calculate l: + // If there are any seconds beyond complete hours, add 1 to account for the incomplete hour + // Convert the result to int128 using Math64x64.fromUInt + int128 l = Math64x64.fromUInt(hoursRemainingInB + (secondsRemainingInB % 1 hours > 0 ? 1 : 0)); // calculate the overcounted (demurraged) k (in day A) and l (in day B) hours // note that the hours l are not demurraged as it is current day by construction