Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: prevent validator signatures before latest proposed retrieval #163

Merged
merged 5 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions src/MinterGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ contract MinterGateway is IMinterGateway, ContinuousIndexing, ERC712Extended {
uint40 updateTimestamp;
uint40 penalizedUntilTimestamp;
uint40 frozenUntilTimestamp;
uint40 latestProposedRetrievalTimestamp;
}

/* ============ Variables ============ */
Expand Down Expand Up @@ -228,6 +229,7 @@ contract MinterGateway is IMinterGateway, ContinuousIndexing, ERC712Extended {
revert RetrievalsExceedCollateral(updatedTotalPendingRetrievals_, currentCollateral_);
}

minterState_.latestProposedRetrievalTimestamp = uint40(block.timestamp);
minterState_.totalPendingRetrievals = updatedTotalPendingRetrievals_;
_pendingCollateralRetrievals[msg.sender][retrievalId_] = safeCollateral_;

Expand Down Expand Up @@ -580,6 +582,11 @@ contract MinterGateway is IMinterGateway, ContinuousIndexing, ERC712Extended {
return _minterStates[minter_].penalizedUntilTimestamp;
}

/// @inheritdoc IMinterGateway
function latestProposedRetrievalOf(address minter_) external view returns (uint40) {
deluca-mike marked this conversation as resolved.
Show resolved Hide resolved
return _minterStates[minter_].latestProposedRetrievalTimestamp;
}

/// @inheritdoc IMinterGateway
function getPenaltyForMissedCollateralUpdates(address minter_) external view returns (uint240) {
uint112 penaltyPrincipal_ = _getPenaltyPrincipalForMissedCollateralUpdates(minter_);
Expand Down Expand Up @@ -866,13 +873,20 @@ contract MinterGateway is IMinterGateway, ContinuousIndexing, ERC712Extended {
* @param newTimestamp_ The timestamp of the collateral update.
*/
function _updateCollateral(address minter_, uint240 amount_, uint40 newTimestamp_) internal {
uint40 lastUpdateTimestamp_ = _minterStates[minter_].updateTimestamp;
MinterState storage minterState_ = _minterStates[minter_];

// MinterGateway already has more recent collateral update
if (newTimestamp_ <= lastUpdateTimestamp_) revert StaleCollateralUpdate(newTimestamp_, lastUpdateTimestamp_);
// The earliest allowed timestamp for a collateral update is the maximum of the last update timestamp and the latest proposed retrieval timestamp.
uint40 earliestAllowedTimestamp_ = UIntMath.max40(
toninorair marked this conversation as resolved.
Show resolved Hide resolved
minterState_.updateTimestamp,
minterState_.latestProposedRetrievalTimestamp
);

if (newTimestamp_ <= earliestAllowedTimestamp_) {
revert StaleCollateralUpdate(newTimestamp_, earliestAllowedTimestamp_);
}

_minterStates[minter_].collateral = amount_;
_minterStates[minter_].updateTimestamp = newTimestamp_;
minterState_.collateral = amount_;
minterState_.updateTimestamp = newTimestamp_;
}

/* ============ Internal View/Pure Functions ============ */
Expand Down
11 changes: 7 additions & 4 deletions src/interfaces/IMinterGateway.sol
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ interface IMinterGateway is IContinuousIndexing, IERC712 {
/// If `validators`, `signatures`, `timestamps` lengths do not match.
error SignatureArrayLengthsMismatch();

/// @notice Emitted when calling `updateCollateral` if Minter Gateway has more fresh collateral update.
error StaleCollateralUpdate(uint40 newTimestamp, uint40 lastCollateralUpdate);
/// @notice Emitted when updating collateral with a timestamp earlier than allowed.
error StaleCollateralUpdate(uint40 newTimestamp, uint40 earliestAllowedTimestamp);

/// @notice Emitted when calling `deactivateMinter` with a minter still approved in TTG Registrar.
error StillApprovedMinter();
Expand Down Expand Up @@ -362,6 +362,9 @@ interface IMinterGateway is IContinuousIndexing, IERC712 {
/// @notice The timestamp until which minter is already penalized for missed collateral updates.
function penalizedUntilOf(address minter) external view returns (uint40);

/// @notice The timestamp when `minter` created their latest retrieval proposal.
function latestProposedRetrievalOf(address minter) external view returns (uint40);

/// @notice The penalty for missed collateral updates. Penalized once per missed interval.
function getPenaltyForMissedCollateralUpdates(address minter) external view returns (uint240);

Expand All @@ -386,10 +389,10 @@ interface IMinterGateway is IContinuousIndexing, IERC712 {
address minter
) external view returns (uint48 mintId, uint40 createdAt, address destination, uint240 amount);

/// @notice The minter's proposeRetrieval proposal amount
/// @notice The amount of a pending retrieval request for an active minter.
function pendingCollateralRetrievalOf(address minter, uint256 retrievalId) external view returns (uint240);

/// @notice The total amount of active proposeRetrieval requests per minter
/// @notice The total amount of pending retrieval requests for an active minter.
function totalPendingCollateralRetrievalOf(address minter) external view returns (uint240);

/// @notice The timestamp when minter becomes unfrozen after being frozen by validator.
Expand Down
Loading
Loading