-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch fixes some items in regards to a user signing `isReplayable`. Specifically, when a user signs an operation, they need to specify if the quark operation is replayable or not. When not, the state manager nonce _must be_ `bytes32(uint256(-1))`, but when it is replayable, the first play _must be_ `op.nonce`. If the user doesn't sign `isReplayable`, then we'd need to enforce that the first play is `replayToken = op.nonce`, which is bad since it that script could (if a bad nonce is chosen) end up replayable, which is an attack vector for a semi-bad client decision. Thus, we add this check to the user's signature and all things should be good in the world. Also, we start to fix a bit of verbiage to make things a bit nicer. Techncially, while it's missing about 200 new tests, this should be a complete implementation. Whitespace changes for fmt check
- Loading branch information
Showing
91 changed files
with
2,766 additions
and
1,149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
pragma solidity 0.8.23; | ||
pragma solidity 0.8.27; | ||
|
||
/** | ||
* @title Code Jar | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
pragma solidity 0.8.27; | ||
|
||
import {IQuarkWallet} from "quark-core/src/QuarkWallet.sol"; | ||
import {QuarkNonceManager} from "quark-core/src/QuarkNonceManager.sol"; | ||
|
||
/** | ||
* @title Cancel Core Script | ||
* @notice Core transaction script that can be used to cancel quark operations. | ||
* @author Legend Labs, Inc. | ||
*/ | ||
contract Cancel { | ||
/** | ||
* @notice May cancel a script by being run as a no-op (no operation). | ||
*/ | ||
function nop() external pure {} | ||
|
||
/** | ||
* @notice Cancels a script by calling into nonce manager to cancel the script's nonce. | ||
* @param nonce The nonce of the quark operation to cancel (exhaust) | ||
*/ | ||
function cancel(bytes32 nonce) external { | ||
nonceManager().cancel(nonce); | ||
} | ||
|
||
/** | ||
* @notice Cancels many scripts by calling into nonce manager to cancel each script's nonce. | ||
* @param nonces A list of nonces of the quark operations to cancel (exhaust) | ||
*/ | ||
function cancelMany(bytes32[] calldata nonces) external { | ||
QuarkNonceManager manager = nonceManager(); | ||
for (uint256 i = 0; i < nonces.length; ++i) { | ||
bytes32 nonce = nonces[i]; | ||
manager.cancel(nonce); | ||
} | ||
} | ||
|
||
function nonceManager() internal view returns (QuarkNonceManager) { | ||
return QuarkNonceManager(IQuarkWallet(address(this)).nonceManager()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
src/quark-core-scripts/src/vendor/uniswap_v3_periphery/PoolAddress.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,79 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
pragma solidity 0.8.23; | ||
pragma solidity 0.8.27; | ||
|
||
import {IQuarkWallet} from "quark-core/src/interfaces/IQuarkWallet.sol"; | ||
|
||
library QuarkNonceManagerMetadata { | ||
/// @notice Represents the unclaimed bytes32 value. | ||
bytes32 internal constant FREE = bytes32(uint256(0)); | ||
|
||
/// @notice A token that implies a Quark Operation is no longer replayable. | ||
bytes32 internal constant EXHAUSTED = bytes32(type(uint256).max); | ||
} | ||
|
||
/** | ||
* @title Quark Nonce Manager | ||
* @notice Contract for managing nonces for Quark wallets | ||
* @author Compound Labs, Inc. | ||
*/ | ||
contract QuarkNonceManager { | ||
error NonReplayableNonce(address wallet, bytes32 nonce, bytes32 submissionToken); | ||
error NonReplayableNonce(address wallet, bytes32 nonce, bytes32 submissionToken, bool exhausted); | ||
error InvalidNonce(address wallet, bytes32 nonce); | ||
error InvalidSubmissionToken(address wallet, bytes32 nonce, bytes32 submissionToken); | ||
|
||
event NonceSubmitted(address wallet, bytes32 nonce, bytes32 submissionToken); | ||
event NonceCanceled(address wallet, bytes32 nonce); | ||
|
||
/// @notice Represents the unclaimed bytes32 value. | ||
bytes32 public constant FREE = bytes32(uint256(0)); | ||
bytes32 public constant FREE = QuarkNonceManagerMetadata.FREE; | ||
|
||
/// @notice A token that implies a Quark Operation is no longer replayable. | ||
bytes32 public constant EXHAUSTED = bytes32(type(uint256).max); | ||
bytes32 public constant EXHAUSTED = QuarkNonceManagerMetadata.EXHAUSTED; | ||
|
||
/// @notice Mapping from nonces to last used submission token. | ||
mapping(address wallet => mapping(bytes32 nonce => bytes32 lastToken)) public nonceSubmissions; | ||
mapping(address wallet => mapping(bytes32 nonce => bytes32 lastToken)) public submissions; | ||
|
||
/** | ||
* @notice Returns the nonce token (last submission token) for a given nonce. For finalized scripts, this will be `uint256(-1)`. For unclaimed nonces, this will be `uint256(0)`. Otherwise, it will be the next value in the replay chain. | ||
* @param wallet The wallet for which to get the nonce token. | ||
* @param nonce The nonce for the given request. | ||
* @return submissionToken The last used submission token, or 0 if unused or -1 if finalized. | ||
* @notice Ensures a given nonce is canceled for sender. An un-used nonce will not be usable in the future, and a replayable nonce will no longer be replayable. This is a no-op for already canceled operations. | ||
* @param nonce The nonce of the chain to cancel. | ||
*/ | ||
function getNonceSubmission(address wallet, bytes32 nonce) external view returns (bytes32 submissionToken) { | ||
return nonceSubmissions[wallet][nonce]; | ||
function cancel(bytes32 nonce) external { | ||
submissions[msg.sender][nonce] = EXHAUSTED; | ||
emit NonceCanceled(msg.sender, nonce); | ||
} | ||
|
||
/** | ||
* @notice Attempts a first or subsequent submission of a given nonce from a wallet. | ||
* @param nonce The nonce of the chain to submit. | ||
* @param submissionToken The submission token of the submission. For single-use operations, set `submissionToken` to `uint256(-1)`. For first-use replayable operations, set `submissionToken` = `nonce`. | ||
* @param isReplayable True only if the operation has been marked as replayable. Otherwise, submission token must be the EXHAUSTED value. | ||
* @param submissionToken The token for this submission. For single-use operations, set `submissionToken` to `uint256(-1)`. For first-use replayable operations, set `submissionToken` = `nonce`. Otherwise, the next submission token from the nonce-chain. | ||
*/ | ||
function submitNonceToken(bytes32 nonce, bytes32 submissionToken) external { | ||
bytes32 lastTokenSubmission = nonceSubmissions[msg.sender][nonce]; | ||
function submit(bytes32 nonce, bool isReplayable, bytes32 submissionToken) external { | ||
bytes32 lastTokenSubmission = submissions[msg.sender][nonce]; | ||
if (lastTokenSubmission == EXHAUSTED) { | ||
revert NonReplayableNonce(msg.sender, nonce, submissionToken); | ||
revert NonReplayableNonce(msg.sender, nonce, submissionToken, true); | ||
} | ||
// Defense-in-depth check for `nonce != FREE` and `nonce != EXHAUSTED` | ||
if (nonce == FREE || nonce == EXHAUSTED) { | ||
revert InvalidNonce(msg.sender, nonce); | ||
} | ||
// Defense-in-depth check for `submissionToken != FREE` and `submissionToken != EXHAUSTED` | ||
if (submissionToken == FREE || submissionToken == EXHAUSTED) { | ||
revert InvalidSubmissionToken(msg.sender, nonce, submissionToken); | ||
} | ||
|
||
bool validFirstPlay = lastTokenSubmission == FREE && submissionToken == nonce; | ||
|
||
/* let validFirstPlayOrReplay = validFirstPlay or validReplay [with short-circuiting] */ | ||
bool validFirstPlayOrReplay = | ||
lastTokenSubmission == FREE || keccak256(abi.encodePacked(submissionToken)) == lastTokenSubmission; | ||
validFirstPlay || keccak256(abi.encodePacked(submissionToken)) == lastTokenSubmission; | ||
|
||
if (!validFirstPlayOrReplay) { | ||
revert InvalidSubmissionToken(msg.sender, nonce, submissionToken); | ||
} | ||
|
||
nonceSubmissions[msg.sender][nonce] = submissionToken; | ||
// Note: even with a valid submission token, we always set non-replayables to exhausted (e.g. for cancellations) | ||
submissions[msg.sender][nonce] = isReplayable ? submissionToken : EXHAUSTED; | ||
emit NonceSubmitted(msg.sender, nonce, submissionToken); | ||
} | ||
} |
Oops, something went wrong.