Omniscia Pirex Audit

PxCvx Manual Review Findings

PxCvx Manual Review Findings

PCX-01M: Snapshot Initialization Race Condition

Description:

The snapshot of the currentEpoch can be written to twice under an edge case whereby the takeEpochSnapshot function is invoked before the first operator has been set.

Impact:

The snapshot taken for the particular epoch will be incorrectly replaced thereby yielding a different snapshot for the same epoch.

Example:

contracts/PxCvx.sol
198/**
199 @notice Snapshot token balances for the current epoch
200 */
201function takeEpochSnapshot() external onlyOperatorOrNotPaused {
202 uint256 currentEpoch = getCurrentEpoch();
203
204 // If snapshot has not been set for current epoch, take snapshot
205 if (epochs[currentEpoch].snapshotId == 0) {
206 epochs[currentEpoch].snapshotId = _snapshot();
207 }
208}

Recommendation:

We advise this scenario to be prohibited by ensuring the onlyOperatorOrNotPaused modifier also validates that the operator it reads from storage already is not equal to the zero-address (address(0)). Alternatively, the contract should be deployed in a paused state immediately to prevent this scenario by setting the pause status in its constructor.

Alleviation:

The code has been updated to include an operator check in the onlyOperatorOrNotPaused modifier as advised thereby alleviating this exhibit.