Refactor Time library to use valueBefore/valueAfter (#4555)
Co-authored-by: Francisco <fg@frang.io>
This commit is contained in:
@ -60,7 +60,7 @@ contract AccessManager is Context, Multicall, IAccessManager {
|
||||
// Structure that stores the details for a group/account pair. This structure fits into a single slot.
|
||||
struct Access {
|
||||
// Timepoint at which the user gets the permission. If this is either 0, or in the future, the group permission
|
||||
// is not available. Should be checked using {Time-isSetAndPast}
|
||||
// is not available.
|
||||
uint48 since;
|
||||
// delay for execution. Only applies to restricted() / relay() calls. This does not restrict access to
|
||||
// functions that use the `onlyGroup` modifier.
|
||||
@ -235,7 +235,7 @@ contract AccessManager is Context, Multicall, IAccessManager {
|
||||
return (true, 0);
|
||||
} else {
|
||||
(uint48 inGroupSince, uint32 currentDelay, , ) = getAccess(groupId, account);
|
||||
return (inGroupSince.isSetAndPast(Time.timestamp()), currentDelay);
|
||||
return (inGroupSince != 0 && inGroupSince <= Time.timestamp(), currentDelay);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ import {Governor} from "../Governor.sol";
|
||||
import {IVotes} from "../utils/IVotes.sol";
|
||||
import {IERC5805} from "../../interfaces/IERC5805.sol";
|
||||
import {SafeCast} from "../../utils/math/SafeCast.sol";
|
||||
import {Time} from "../../utils/types/Time.sol";
|
||||
|
||||
/**
|
||||
* @dev Extension of {Governor} for voting weight extraction from an {ERC20Votes} token, or since v4.5 an {ERC721Votes} token.
|
||||
@ -26,7 +27,7 @@ abstract contract GovernorVotes is Governor {
|
||||
try token.clock() returns (uint48 timepoint) {
|
||||
return timepoint;
|
||||
} catch {
|
||||
return SafeCast.toUint48(block.number);
|
||||
return Time.blockNumber();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import {EIP712} from "../../utils/cryptography/EIP712.sol";
|
||||
import {Checkpoints} from "../../utils/structs/Checkpoints.sol";
|
||||
import {SafeCast} from "../../utils/math/SafeCast.sol";
|
||||
import {ECDSA} from "../../utils/cryptography/ECDSA.sol";
|
||||
import {Time} from "../../utils/types/Time.sol";
|
||||
|
||||
/**
|
||||
* @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be
|
||||
@ -55,7 +56,7 @@ abstract contract Votes is Context, EIP712, Nonces, IERC5805 {
|
||||
* checkpoints (and voting), in which case {CLOCK_MODE} should be overridden as well to match.
|
||||
*/
|
||||
function clock() public view virtual returns (uint48) {
|
||||
return SafeCast.toUint48(block.number);
|
||||
return Time.blockNumber();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,7 +65,7 @@ abstract contract Votes is Context, EIP712, Nonces, IERC5805 {
|
||||
// solhint-disable-next-line func-name-mixedcase
|
||||
function CLOCK_MODE() public view virtual returns (string memory) {
|
||||
// Check that the clock was not modified
|
||||
if (clock() != block.number) {
|
||||
if (clock() != Time.blockNumber()) {
|
||||
revert ERC6372InconsistentClock();
|
||||
}
|
||||
return "mode=blocknumber&from=default";
|
||||
|
||||
@ -33,13 +33,6 @@ library Time {
|
||||
return SafeCast.toUint48(block.number);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Check if a timepoint is set, and in the past.
|
||||
*/
|
||||
function isSetAndPast(uint48 timepoint, uint48 ref) internal pure returns (bool) {
|
||||
return timepoint != 0 && timepoint <= ref;
|
||||
}
|
||||
|
||||
// ==================================================== Delay =====================================================
|
||||
/**
|
||||
* @dev A `Delay` is a uint32 duration that can be programmed to change value automatically at a given point in the
|
||||
@ -52,12 +45,12 @@ library Time {
|
||||
* still apply for some time.
|
||||
*
|
||||
*
|
||||
* The `Delay` type is 128 bits long, and packs the following:
|
||||
* The `Delay` type is 112 bits long, and packs the following:
|
||||
*
|
||||
* ```
|
||||
* | [uint48]: effect date (timepoint)
|
||||
* | | [uint32]: current value (duration)
|
||||
* ↓ ↓ ↓ [uint32]: pending value (duration)
|
||||
* | | [uint32]: value before (duration)
|
||||
* ↓ ↓ ↓ [uint32]: value after (duration)
|
||||
* 0xAAAAAAAAAAAABBBBBBBBCCCCCCCC
|
||||
* ```
|
||||
*
|
||||
@ -78,8 +71,8 @@ library Time {
|
||||
* change after this timepoint. If the effect timepoint is 0, then the pending value should not be considered.
|
||||
*/
|
||||
function getFullAt(Delay self, uint48 timepoint) internal pure returns (uint32, uint32, uint48) {
|
||||
(uint32 oldValue, uint32 newValue, uint48 effect) = self.unpack();
|
||||
return effect.isSetAndPast(timepoint) ? (newValue, 0, 0) : (oldValue, newValue, effect);
|
||||
(uint32 valueBefore, uint32 valueAfter, uint48 effect) = self.unpack();
|
||||
return effect <= timepoint ? (valueAfter, 0, 0) : (valueBefore, valueAfter, effect);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,13 +98,6 @@ library Time {
|
||||
return self.getAt(timestamp());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Update a Delay object so that a new duration takes effect at a given timepoint.
|
||||
*/
|
||||
function withUpdateAt(Delay self, uint32 newValue, uint48 effect) internal view returns (Delay) {
|
||||
return pack(self.get(), newValue, effect);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Update a Delay object so that it takes a new duration after a timepoint that is automatically computed to
|
||||
* enforce the old delay at the moment of the update. Returns the updated Delay object and the timestamp when the
|
||||
@ -121,25 +107,26 @@ library Time {
|
||||
uint32 value = self.get();
|
||||
uint32 setback = uint32(Math.max(minSetback, value > newValue ? value - newValue : 0));
|
||||
uint48 effect = timestamp() + setback;
|
||||
return (self.withUpdateAt(newValue, effect), effect);
|
||||
return (pack(value, newValue, effect), effect);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Split a delay into its components: oldValue, newValue and effect (transition timepoint).
|
||||
* @dev Split a delay into its components: valueBefore, valueAfter and effect (transition timepoint).
|
||||
*/
|
||||
function unpack(Delay self) internal pure returns (uint32, uint32, uint48) {
|
||||
uint112 raw = Delay.unwrap(self);
|
||||
return (
|
||||
uint32(raw), // oldValue
|
||||
uint32(raw >> 32), // newValue
|
||||
uint48(raw >> 64) // effect
|
||||
);
|
||||
|
||||
uint32 valueAfter = uint32(raw);
|
||||
uint32 valueBefore = uint32(raw >> 32);
|
||||
uint48 effect = uint48(raw >> 64);
|
||||
|
||||
return (valueBefore, valueAfter, effect);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev pack the components into a Delay object.
|
||||
*/
|
||||
function pack(uint32 oldValue, uint32 newValue, uint48 effect) internal pure returns (Delay) {
|
||||
return Delay.wrap(uint112(oldValue) | (uint112(newValue) << 32) | (uint112(effect) << 64));
|
||||
function pack(uint32 valueBefore, uint32 valueAfter, uint48 effect) internal pure returns (Delay) {
|
||||
return Delay.wrap((uint112(effect) << 64) | (uint112(valueBefore) << 32) | uint112(valueAfter));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user