code-423n4 / 2022-08-olympus-findings

5 stars 4 forks source link

## block.timestamp used as time proxy #482

Closed code423n4 closed 1 year ago

code423n4 commented 2 years ago

Lines of code

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Heart.sol#L94

Vulnerability details

block.timestamp used as time proxy

Summary:

Risk of using block.timestamp for time should be considered.

Details:

block.timestamp is not an ideal proxy for time because of issues with synchronization, miner manipulation and changing block times.

This kind of issue may affect the code allowing or reverting the code before the expected deadline or modifying the normal functioning for example.

References

SWC ID: 116

Github Permalinks

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/PRICE.sol#L143 lastObservationTime = uint48(block.timestamp);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/PRICE.sol#L146 emit NewObservation(block.timestamp, currentPrice, _movingAverage);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/PRICE.sol#L165 if (updatedAt < block.timestamp - 3 * uint256(observationFrequency))

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/PRICE.sol#L171 if (updatedAt < block.timestamp - uint256(observationFrequency))

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/PRICE.sol#L215 if (startObservations.length != numObs || lastObservationTime > uint48(block.timestamp))

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/RANGE.sol#L85 lastActive: uint48(block.timestamp),

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/RANGE.sol#L92 lastActive: uint48(block.timestamp),

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/RANGE.sol#L136 _range.high.lastActive = uint48(block.timestamp);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/RANGE.sol#L138 emit WallDown(true, block.timestamp, capacity_);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/RANGE.sol#L148 _range.low.lastActive = uint48(block.timestamp);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/RANGE.sol#L150 emit WallDown(false, block.timestamp, capacity_);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/RANGE.sol#L191 lastActive: uint48(block.timestamp),

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/RANGE.sol#L200 lastActive: uint48(block.timestamp),

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/RANGE.sol#L207 emit WallUp(high, block.timestamp, capacity);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/RANGE.sol#L231 emit CushionDown(high_, block.timestamp);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/modules/RANGE.sol#L233 emit CushionUp(high, block.timestamp, marketCapacity);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Governance.sol#L171 block.timestamp,

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Governance.sol#L212 if (block.timestamp > proposal.submissionTimestamp + ACTIVATION_DEADLINE) {

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Governance.sol#L227 if (block.timestamp < activeProposal.activationTimestamp + GRACE_PERIOD) {

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Governance.sol#L231 activeProposal = ActivatedProposal(proposalId_, block.timestamp);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Governance.sol#L235 emit ProposalActivated(proposalId_, block.timestamp);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Governance.sol#L272 if (block.timestamp < activeProposal.activationTimestamp + EXECUTION_TIMELOCK) {

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Heart.sol#L63 lastBeat = block.timestamp;

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Heart.sol#L94 if (block.timestamp < lastBeat + frequency()) revert Heart_OutOfCycle();

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Heart.sol#L108 emit Beat(block.timestamp);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Heart.sol#L131 lastBeat = block.timestamp - frequency();

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Operator.sol#L128 lastRegen: uint48(block.timestamp),

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Operator.sol#L210 uint48(block.timestamp) >= RANGE.lastActive(true) + uint48(config_.regenWait) &&

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Operator.sol#L216 uint48(block.timestamp) >= RANGE.lastActive(false) + uint48(config_.regenWait) &&

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Operator.sol#L404 conclusion: uint48(block.timestamp + config_.cushionDuration),

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Operator.sol#L456 conclusion: uint48(block.timestamp + config_.cushionDuration),

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Operator.sol#L708 _status.high.lastRegen = uint48(block.timestamp);

https://github.com/code-423n4/2022-08-olympus/blob/549b96bcf8b97807738572605f6b1e26b33ef411/src/policies/Operator.sol#L720 _status.low.lastRegen = uint48(block.timestamp);

Mitigation

Consider using an oracle for precision Consider the risk of using block.timestamp as time proxy and evaluate if block numbers can be used as an approximation for the application logic. Both have risks that need to be factored in.

fullyallocated commented 2 years ago

The margin of error for timestamp drift in block production doesn't materially affect the intended behavior of the contract

0xean commented 1 year ago

closing as invalid.