diff --git a/src/quark-core/src/QuarkNonceManager.sol b/src/quark-core/src/QuarkNonceManager.sol index a567e3df..8c818be3 100644 --- a/src/quark-core/src/QuarkNonceManager.sol +++ b/src/quark-core/src/QuarkNonceManager.sol @@ -3,6 +3,14 @@ pragma solidity 0.8.23; 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 @@ -16,10 +24,10 @@ contract QuarkNonceManager { event NonceSubmitted(address wallet, bytes32 nonce, bytes32 submissionToken); /// @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 submissions; diff --git a/src/quark-core/src/QuarkScript.sol b/src/quark-core/src/QuarkScript.sol index 8cb178f5..8515eca4 100644 --- a/src/quark-core/src/QuarkScript.sol +++ b/src/quark-core/src/QuarkScript.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.23; -import {QuarkWallet, IHasSignerExecutor} from "quark-core/src/QuarkWallet.sol"; +import {QuarkWallet, QuarkWalletMetadata, IHasSignerExecutor} from "quark-core/src/QuarkWallet.sol"; +import {QuarkNonceManagerMetadata} from "quark-core/src/QuarkNonceManager.sol"; /** * @title Quark Script @@ -13,19 +14,6 @@ abstract contract QuarkScript { error InvalidActiveNonce(); error InvalidActiveSubmissionToken(); - /// @notice Well-known storage slot for the currently executing script's callback address (if any) - bytes32 public constant CALLBACK_SLOT = bytes32(uint256(keccak256("quark.v1.callback")) - 1); - - /// @notice Well-known storage slot for the currently executing script's address (if any) - bytes32 public constant ACTIVE_SCRIPT_SLOT = bytes32(uint256(keccak256("quark.v1.active.script")) - 1); - - /// @notice Well-known -- - bytes32 public constant ACTIVE_NONCE_SLOT = bytes32(uint256(keccak256("quark.v1.active.nonce")) - 1); - - /// @notice Well-known -- - bytes32 public constant ACTIVE_SUBMISSION_TOKEN_SLOT = - bytes32(uint256(keccak256("quark.v1.active.submissionToken")) - 1); - /// @notice Storage location for the re-entrancy guard bytes32 internal constant REENTRANCY_FLAG_SLOT = bytes32(uint256(keccak256("quark.scripts.reentrancy.guard.v1")) - 1); @@ -82,8 +70,8 @@ abstract contract QuarkScript { } function allowCallback() internal { - bytes32 callbackSlot = CALLBACK_SLOT; - bytes32 activeScriptSlot = ACTIVE_SCRIPT_SLOT; + bytes32 callbackSlot = QuarkWalletMetadata.CALLBACK_SLOT; + bytes32 activeScriptSlot = QuarkWalletMetadata.ACTIVE_SCRIPT_SLOT; assembly { // TODO: Move to TLOAD/TSTORE after updating Solidity version to >=0.8.24 let activeScript := sload(activeScriptSlot) @@ -92,7 +80,7 @@ abstract contract QuarkScript { } function clearCallback() internal { - bytes32 callbackSlot = CALLBACK_SLOT; + bytes32 callbackSlot = QuarkWalletMetadata.CALLBACK_SLOT; assembly { // TODO: Move to TSTORE after updating Solidity version to >=0.8.24 sstore(callbackSlot, 0) @@ -133,7 +121,7 @@ abstract contract QuarkScript { // Note: this may not be accurate after any nested calls from a script function getActiveNonce() internal view returns (bytes32) { - bytes32 activeNonceSlot = ACTIVE_NONCE_SLOT; + bytes32 activeNonceSlot = QuarkWalletMetadata.ACTIVE_NONCE_SLOT; bytes32 value; assembly { value := sload(activeNonceSlot) @@ -144,7 +132,7 @@ abstract contract QuarkScript { // Note: this may not be accurate after any nested calls from a script function getActiveSubmissionToken() internal view returns (bytes32) { - bytes32 activeSubmissionTokenSlot = ACTIVE_SUBMISSION_TOKEN_SLOT; + bytes32 activeSubmissionTokenSlot = QuarkWalletMetadata.ACTIVE_SUBMISSION_TOKEN_SLOT; bytes32 value; assembly { value := sload(activeSubmissionTokenSlot) @@ -160,7 +148,7 @@ abstract contract QuarkScript { bytes32 submissionToken = getActiveSubmissionToken(); uint256 n; - if (submissionToken == bytes32(type(uint256).max)) { + if (submissionToken == QuarkNonceManagerMetadata.EXHAUSTED) { return 0; } diff --git a/src/quark-core/src/QuarkWallet.sol b/src/quark-core/src/QuarkWallet.sol index 57579c10..5187016d 100644 --- a/src/quark-core/src/QuarkWallet.sol +++ b/src/quark-core/src/QuarkWallet.sol @@ -39,6 +39,19 @@ library QuarkWalletMetadata { /// @notice The EIP-712 domain typehash used for MultiQuarkOperations for this version of QuarkWallet bytes32 internal constant MULTI_QUARK_OPERATION_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version)"); + + /// @notice Well-known storage slot for the currently executing script's callback address (if any) + bytes32 internal constant CALLBACK_SLOT = bytes32(uint256(keccak256("quark.v1.callback")) - 1); + + /// @notice Well-known storage slot for the currently executing script's address (if any) + bytes32 internal constant ACTIVE_SCRIPT_SLOT = bytes32(uint256(keccak256("quark.v1.active.script")) - 1); + + /// @notice Well-known storage slot for the nonce of the script that's currently executing. + bytes32 internal constant ACTIVE_NONCE_SLOT = bytes32(uint256(keccak256("quark.v1.active.nonce")) - 1); + + /// @notice Well-known storage slot for the submission token of the script thatg's currently executing. + bytes32 internal constant ACTIVE_SUBMISSION_TOKEN_SLOT = + bytes32(uint256(keccak256("quark.v1.active.submissionToken")) - 1); } /** @@ -112,17 +125,16 @@ contract QuarkWallet is IERC1271 { ); /// @notice Well-known storage slot for the currently executing script's callback address (if any) - bytes32 public constant CALLBACK_SLOT = bytes32(uint256(keccak256("quark.v1.callback")) - 1); + bytes32 public constant CALLBACK_SLOT = QuarkWalletMetadata.CALLBACK_SLOT; /// @notice Well-known storage slot for the currently executing script's address (if any) - bytes32 public constant ACTIVE_SCRIPT_SLOT = bytes32(uint256(keccak256("quark.v1.active.script")) - 1); + bytes32 public constant ACTIVE_SCRIPT_SLOT = QuarkWalletMetadata.ACTIVE_SCRIPT_SLOT; - /// @notice Well-known -- - bytes32 public constant ACTIVE_NONCE_SLOT = bytes32(uint256(keccak256("quark.v1.active.nonce")) - 1); + /// @notice Well-known storage slot for the nonce of the script that's currently executing. + bytes32 public constant ACTIVE_NONCE_SLOT = QuarkWalletMetadata.ACTIVE_NONCE_SLOT; - /// @notice Well-known -- - bytes32 public constant ACTIVE_SUBMISSION_TOKEN_SLOT = - bytes32(uint256(keccak256("quark.v1.active.submissionToken")) - 1); + /// @notice Well-known storage slot for the submission token of the script thatg's currently executing. + bytes32 public constant ACTIVE_SUBMISSION_TOKEN_SLOT = QuarkWalletMetadata.ACTIVE_SUBMISSION_TOKEN_SLOT; /// @notice The magic value to return for valid ERC1271 signature bytes4 internal constant EIP_1271_MAGIC_VALUE = 0x1626ba7e; diff --git a/test/lib/CancelOtherScript.sol b/test/lib/CancelOtherScript.sol index 515cfac0..d065924c 100644 --- a/test/lib/CancelOtherScript.sol +++ b/test/lib/CancelOtherScript.sol @@ -11,15 +11,15 @@ contract CancelOtherScript is QuarkScript { emit CancelNonce(); } - function checkNonce() public returns (bytes32) { + function checkNonce() public view returns (bytes32) { return getActiveNonce(); } - function checkSubmissionToken() public returns (bytes32) { + function checkSubmissionToken() public view returns (bytes32) { return getActiveSubmissionToken(); } - function checkReplayCount() public returns (uint256) { + function checkReplayCount() public view returns (uint256) { return getActiveReplayCount(); } } diff --git a/test/quark-core/QuarkWallet.t.sol b/test/quark-core/QuarkWallet.t.sol index a160643c..08c49d0f 100644 --- a/test/quark-core/QuarkWallet.t.sol +++ b/test/quark-core/QuarkWallet.t.sol @@ -235,7 +235,6 @@ contract QuarkWalletTest is Test { // gas: do not meter set-up vm.pauseGasMetering(); - Counter counter = new Counter(); assertEq(counter.number(), 0); bytes memory maxCounterScript = new YulHelper().getCode("MaxCounterScript.sol/MaxCounterScript.json");