Skip to content

Commit 7bf74a2

Browse files
committed
Commit types folder that was initially ignore by .gitignore
1 parent b4a70c5 commit 7bf74a2

File tree

1 file changed

+143
-0
lines changed
  • src/lib/openzeppelin-contracts-upgradeable-v5/lib/openzeppelin-contracts/contracts/utils/types

1 file changed

+143
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// SPDX-License-Identifier: MIT
2+
// OpenZeppelin Contracts (last updated v5.0.0) (utils/types/Time.sol)
3+
4+
pragma solidity ^0.8.20;
5+
6+
import {Math} from "../math/Math.sol";
7+
import {SafeCast} from "../math/SafeCast.sol";
8+
9+
/**
10+
* @dev This library provides helpers for manipulating time-related objects.
11+
*
12+
* It uses the following types:
13+
* - `uint48` for timepoints
14+
* - `uint32` for durations
15+
*
16+
* While the library doesn't provide specific types for timepoints and duration, it does provide:
17+
* - a `Delay` type to represent duration that can be programmed to change value automatically at a given point
18+
* - additional helper functions
19+
*/
20+
library Time {
21+
using Time for *;
22+
23+
/**
24+
* @dev Get the block timestamp as a Timepoint.
25+
*/
26+
function timestamp() internal view returns (uint48) {
27+
return SafeCast.toUint48(block.timestamp);
28+
}
29+
30+
/**
31+
* @dev Get the block number as a Timepoint.
32+
*/
33+
function blockNumber() internal view returns (uint48) {
34+
return SafeCast.toUint48(block.number);
35+
}
36+
37+
// ==================================================== Delay =====================================================
38+
/**
39+
* @dev A `Delay` is a uint32 duration that can be programmed to change value automatically at a given point in the
40+
* future. The "effect" timepoint describes when the transitions happens from the "old" value to the "new" value.
41+
* This allows updating the delay applied to some operation while keeping some guarantees.
42+
*
43+
* In particular, the {update} function guarantees that if the delay is reduced, the old delay still applies for
44+
* some time. For example if the delay is currently 7 days to do an upgrade, the admin should not be able to set
45+
* the delay to 0 and upgrade immediately. If the admin wants to reduce the delay, the old delay (7 days) should
46+
* still apply for some time.
47+
*
48+
*
49+
* The `Delay` type is 112 bits long, and packs the following:
50+
*
51+
* ```
52+
* | [uint48]: effect date (timepoint)
53+
* | | [uint32]: value before (duration)
54+
* ↓ ↓ ↓ [uint32]: value after (duration)
55+
* 0xAAAAAAAAAAAABBBBBBBBCCCCCCCC
56+
* ```
57+
*
58+
* NOTE: The {get} and {withUpdate} functions operate using timestamps. Block number based delays are not currently
59+
* supported.
60+
*/
61+
type Delay is uint112;
62+
63+
/**
64+
* @dev Wrap a duration into a Delay to add the one-step "update in the future" feature
65+
*/
66+
function toDelay(uint32 duration) internal pure returns (Delay) {
67+
return Delay.wrap(duration);
68+
}
69+
70+
/**
71+
* @dev Get the value at a given timepoint plus the pending value and effect timepoint if there is a scheduled
72+
* change after this timepoint. If the effect timepoint is 0, then the pending value should not be considered.
73+
*/
74+
function _getFullAt(Delay self, uint48 timepoint)
75+
private
76+
pure
77+
returns (uint32, uint32, uint48)
78+
{
79+
(uint32 valueBefore, uint32 valueAfter, uint48 effect) = self.unpack();
80+
return effect <= timepoint ? (valueAfter, 0, 0) : (valueBefore, valueAfter, effect);
81+
}
82+
83+
/**
84+
* @dev Get the current value plus the pending value and effect timepoint if there is a scheduled change. If the
85+
* effect timepoint is 0, then the pending value should not be considered.
86+
*/
87+
function getFull(Delay self) internal view returns (uint32, uint32, uint48) {
88+
return _getFullAt(self, timestamp());
89+
}
90+
91+
/**
92+
* @dev Get the current value.
93+
*/
94+
function get(Delay self) internal view returns (uint32) {
95+
(uint32 delay,,) = self.getFull();
96+
return delay;
97+
}
98+
99+
/**
100+
* @dev Update a Delay object so that it takes a new duration after a timepoint that is automatically computed to
101+
* enforce the old delay at the moment of the update. Returns the updated Delay object and the timestamp when the
102+
* new delay becomes effective.
103+
*/
104+
function withUpdate(Delay self, uint32 newValue, uint32 minSetback)
105+
internal
106+
view
107+
returns (Delay updatedDelay, uint48 effect)
108+
{
109+
uint32 value = self.get();
110+
uint32 setback = uint32(Math.max(minSetback, value > newValue ? value - newValue : 0));
111+
effect = timestamp() + setback;
112+
return (pack(value, newValue, effect), effect);
113+
}
114+
115+
/**
116+
* @dev Split a delay into its components: valueBefore, valueAfter and effect (transition timepoint).
117+
*/
118+
function unpack(Delay self)
119+
internal
120+
pure
121+
returns (uint32 valueBefore, uint32 valueAfter, uint48 effect)
122+
{
123+
uint112 raw = Delay.unwrap(self);
124+
125+
valueAfter = uint32(raw);
126+
valueBefore = uint32(raw >> 32);
127+
effect = uint48(raw >> 64);
128+
129+
return (valueBefore, valueAfter, effect);
130+
}
131+
132+
/**
133+
* @dev pack the components into a Delay object.
134+
*/
135+
function pack(uint32 valueBefore, uint32 valueAfter, uint48 effect)
136+
internal
137+
pure
138+
returns (Delay)
139+
{
140+
return
141+
Delay.wrap((uint112(effect) << 64) | (uint112(valueBefore) << 32) | uint112(valueAfter));
142+
}
143+
}

0 commit comments

Comments
 (0)