From 399519895b22aa7337cf46f55146aee30b42baeb Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 6 Apr 2025 02:48:06 -0500 Subject: [PATCH 01/17] add pausable --- contracts/pausable/contract/.eslintignore | 1 + contracts/pausable/contract/.eslintrc.cjs | 30 ++++++ contracts/pausable/contract/jest.config.ts | 24 +++++ contracts/pausable/contract/js-resolver.cjs | 16 ++++ contracts/pausable/contract/package.json | 29 ++++++ .../contract/src/MockPausable.compact | 26 +++++ .../pausable/contract/src/Pausable.compact | 61 ++++++++++++ .../contract/src/test/PausableSimulator.ts | 96 +++++++++++++++++++ .../contract/src/test/pausable.test.ts | 77 +++++++++++++++ .../pausable/contract/src/test/types/index.ts | 1 + .../pausable/contract/src/test/types/test.ts | 23 +++++ .../pausable/contract/src/test/utils/index.ts | 1 + .../pausable/contract/src/test/utils/test.ts | 67 +++++++++++++ .../src/witnesses/PausableWitnesses.ts | 3 + .../pausable/contract/src/witnesses/index.ts | 2 + .../pausable/contract/tsconfig.build.json | 5 + contracts/pausable/contract/tsconfig.json | 21 ++++ package.json | 1 + yarn.lock | 11 +++ 19 files changed, 495 insertions(+) create mode 100644 contracts/pausable/contract/.eslintignore create mode 100644 contracts/pausable/contract/.eslintrc.cjs create mode 100644 contracts/pausable/contract/jest.config.ts create mode 100644 contracts/pausable/contract/js-resolver.cjs create mode 100644 contracts/pausable/contract/package.json create mode 100644 contracts/pausable/contract/src/MockPausable.compact create mode 100644 contracts/pausable/contract/src/Pausable.compact create mode 100644 contracts/pausable/contract/src/test/PausableSimulator.ts create mode 100644 contracts/pausable/contract/src/test/pausable.test.ts create mode 100644 contracts/pausable/contract/src/test/types/index.ts create mode 100644 contracts/pausable/contract/src/test/types/test.ts create mode 100644 contracts/pausable/contract/src/test/utils/index.ts create mode 100644 contracts/pausable/contract/src/test/utils/test.ts create mode 100644 contracts/pausable/contract/src/witnesses/PausableWitnesses.ts create mode 100644 contracts/pausable/contract/src/witnesses/index.ts create mode 100644 contracts/pausable/contract/tsconfig.build.json create mode 100644 contracts/pausable/contract/tsconfig.json diff --git a/contracts/pausable/contract/.eslintignore b/contracts/pausable/contract/.eslintignore new file mode 100644 index 00000000..327555cd --- /dev/null +++ b/contracts/pausable/contract/.eslintignore @@ -0,0 +1 @@ +src/artifacts diff --git a/contracts/pausable/contract/.eslintrc.cjs b/contracts/pausable/contract/.eslintrc.cjs new file mode 100644 index 00000000..581f1d49 --- /dev/null +++ b/contracts/pausable/contract/.eslintrc.cjs @@ -0,0 +1,30 @@ +module.exports = { + env: { + browser: true, + es2021: true, + node: true, + jest: true, + }, + extends: [ + 'standard-with-typescript', + 'plugin:prettier/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + ], + overrides: [], + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + project: ['tsconfig.json'], + }, + rules: { + '@typescript-eslint/no-misused-promises': 'off', // https://github.com/typescript-eslint/typescript-eslint/issues/5807 + '@typescript-eslint/no-floating-promises': 'warn', + '@typescript-eslint/promise-function-async': 'off', + '@typescript-eslint/no-redeclare': 'off', + '@typescript-eslint/no-invalid-void-type': 'off', + '@typescript-eslint/no-unsafe-call': 'off', + '@typescript-eslint/no-unsafe-member-access': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/consistent-type-definitions': 'off' + }, +}; diff --git a/contracts/pausable/contract/jest.config.ts b/contracts/pausable/contract/jest.config.ts new file mode 100644 index 00000000..db2dbd5f --- /dev/null +++ b/contracts/pausable/contract/jest.config.ts @@ -0,0 +1,24 @@ +import type { Config } from "@jest/types"; + +const config: Config.InitialOptions = { + preset: "ts-jest/presets/default-esm", + testEnvironment: "node", + verbose: true, + roots: [""], + modulePaths: [""], + passWithNoTests: false, + testMatch: ["**/*.test.ts"], + extensionsToTreatAsEsm: [".ts"], + collectCoverage: true, + resolver: '/js-resolver.cjs', + coverageThreshold: { + global: {}, + }, + reporters: [ + "default", + ["jest-junit", { outputDirectory: "reports", outputName: "report.xml" }], + ["jest-html-reporters", { publicPath: "reports", filename: "report.html" }], + ], +}; + +export default config; diff --git a/contracts/pausable/contract/js-resolver.cjs b/contracts/pausable/contract/js-resolver.cjs new file mode 100644 index 00000000..cc9ed285 --- /dev/null +++ b/contracts/pausable/contract/js-resolver.cjs @@ -0,0 +1,16 @@ +const jsResolver = (path, options) => { + const jsExtRegex = /\.js$/i + const resolver = options.defaultResolver + if (jsExtRegex.test(path) && !options.basedir.includes('node_modules') && !path.includes('node_modules')) { + const newPath = path.replace(jsExtRegex, '.ts'); + try { + return resolver(newPath, options) + } catch { + // use default resolver + } + } + + return resolver(path, options) +} + +module.exports = jsResolver diff --git a/contracts/pausable/contract/package.json b/contracts/pausable/contract/package.json new file mode 100644 index 00000000..33814780 --- /dev/null +++ b/contracts/pausable/contract/package.json @@ -0,0 +1,29 @@ +{ + "name": "@openzeppelin-midnight-contracts/pausable-contract", + "type": "module", + "main": "dist/index.js", + "module": "dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "require": "./dist/index.js", + "import": "./dist/index.js", + "default": "./dist/index.js" + } + }, + "scripts": { + "compact": "find src -name '*.compact' -exec sh -c 'run-compactc \"{}\" \"src/artifacts/$(basename \"{}\" .compact)\"' \\;", + "test": "NODE_OPTIONS=--experimental-vm-modules jest", + "prepack": "yarn build", + "build": "rm -rf dist && tsc --project tsconfig.build.json && cp -Rf ./src/artifacts ./dist/artifacts && cp ./src/Pausable.compact ./dist", + "lint": "eslint src", + "typecheck": "tsc -p tsconfig.json --noEmit" + }, + "devDependencies": { + "@midnight-ntwrk/compact": "workspace:*", + "eslint": "^8.52.0", + "jest": "^29.7.0", + "typescript": "^5.2.2" + } +} diff --git a/contracts/pausable/contract/src/MockPausable.compact b/contracts/pausable/contract/src/MockPausable.compact new file mode 100644 index 00000000..1a90349b --- /dev/null +++ b/contracts/pausable/contract/src/MockPausable.compact @@ -0,0 +1,26 @@ +pragma language_version >= 0.14.0; + +import CompactStandardLibrary; +import Pausable prefix Pausable_; + +export { Pausable__isPaused }; + +export circuit isPaused(): Boolean { + return Pausable_isPaused(); +} + +export circuit assertNotPaused(): [] { + return Pausable_assertNotPaused(); +} + +export circuit assertPaused(): [] { + return Pausable_assertPaused(); +} + +export circuit pause(): [] { + return Pausable__pause(); +} + +export circuit unpause(): [] { + return Pausable__unpause(); +} \ No newline at end of file diff --git a/contracts/pausable/contract/src/Pausable.compact b/contracts/pausable/contract/src/Pausable.compact new file mode 100644 index 00000000..92685f24 --- /dev/null +++ b/contracts/pausable/contract/src/Pausable.compact @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: MIT +pragma language_version >= 0.14.0; + +/** + * @module Pausable. + * @description Pausable allows the implementing contract to implement + * an emergency stop mechanism. Only circuits that call `assertPaused` + * or `assertNotPaused` will be affected by this mechanism. + */ +module Pausable { + import CompactStandardLibrary; + + export ledger _isPaused: Boolean; + + /** + * @description Returns true if the contract is paused, and false otherwise. + * + * @returns {Boolean} True if paused. + */ + export circuit isPaused(): Boolean { + return _isPaused; + } + + /** + * @description Makes a circuit only callable when the contract is paused. + * + * @returns None. + */ + export circuit assertPaused(): [] { + assert _isPaused "Pausable: not paused"; + } + + /** + * @description Makes a circuit only callable when the contract is not paused. + * + * @returns None. + */ + export circuit assertNotPaused(): [] { + assert !_isPaused "Pausable: paused"; + } + + /** + * @description Triggers a stopped state. + * + * @returns None. + */ + export circuit _pause(): [] { + assertNotPaused(); + _isPaused = true; + } + + /** + * @description Lifts the pause on the contract. + * + * @returns None. + */ + export circuit _unpause(): [] { + assertPaused(); + _isPaused = false; + } +} diff --git a/contracts/pausable/contract/src/test/PausableSimulator.ts b/contracts/pausable/contract/src/test/PausableSimulator.ts new file mode 100644 index 00000000..eebce672 --- /dev/null +++ b/contracts/pausable/contract/src/test/PausableSimulator.ts @@ -0,0 +1,96 @@ +import { type CircuitContext, type ContractState, QueryContext, sampleContractAddress, constructorContext } from '@midnight-ntwrk/compact-runtime'; +import { Contract as MockPausable, type Ledger, ledger } from '../artifacts/MockPausable/contract/index.cjs'; +import type { IContractSimulator } from './types'; +import { PausablePrivateState, PausableWitnesses } from '../witnesses'; + +/** + * @description A simulator implementation of an utils contract for testing purposes. + * @template P - The private state type, fixed to UtilsPrivateState. + * @template L - The ledger type, fixed to Contract.Ledger. + */ +export class PausableSimulator + implements IContractSimulator +{ + /** @description The underlying contract instance managing contract logic. */ + readonly contract: MockPausable; + + /** @description The deployed address of the contract. */ + readonly contractAddress: string; + + /** @description The current circuit context, updated by contract operations. */ + circuitContext: CircuitContext; + + /** + * @description Initializes the mock contract. + */ + constructor() { + this.contract = new MockPausable( + PausableWitnesses, + ); + const { + currentPrivateState, + currentContractState, + currentZswapLocalState, + } = this.contract.initialState( + constructorContext({}, '0'.repeat(64)) + ); + this.circuitContext = { + currentPrivateState, + currentZswapLocalState, + originalState: currentContractState, + transactionContext: new QueryContext( + currentContractState.data, + sampleContractAddress(), + ), + }; + this.contractAddress = this.circuitContext.transactionContext.address; + } + + /** + * @description Retrieves the current public ledger state of the contract. + * @returns The ledger state as defined by the contract. + */ + public getCurrentPublicState(): Ledger { + return ledger(this.circuitContext.transactionContext.state); + } + + /** + * @description Retrieves the current private state of the contract. + * @returns The private state of type UtilsPrivateState. + */ + public getCurrentPrivateState(): PausablePrivateState { + return this.circuitContext.currentPrivateState; + } + + /** + * @description Retrieves the current contract state. + * @returns The contract state object. + */ + public getCurrentContractState(): ContractState { + return this.circuitContext.originalState; + } + + /** + * @description Initializes the state. + * @returns None. + */ + public isPaused() { + return this.contract.impureCircuits.isPaused(this.circuitContext).result; + } + + public pause() { + this.circuitContext = this.contract.impureCircuits.pause(this.circuitContext).context; + } + + public unpause() { + this.circuitContext = this.contract.impureCircuits.unpause(this.circuitContext).context; + } + + public assertPaused() { + this.circuitContext = this.contract.impureCircuits.assertPaused(this.circuitContext).context; + } + + public assertNotPaused() { + this.circuitContext = this.contract.impureCircuits.assertNotPaused(this.circuitContext).context; + } +} diff --git a/contracts/pausable/contract/src/test/pausable.test.ts b/contracts/pausable/contract/src/test/pausable.test.ts new file mode 100644 index 00000000..a4e62ae9 --- /dev/null +++ b/contracts/pausable/contract/src/test/pausable.test.ts @@ -0,0 +1,77 @@ +import { it, describe, expect } from '@jest/globals'; +import { PausableSimulator } from './PausableSimulator.js'; + +let pausable: PausableSimulator; + +describe('Pausable', () => { + beforeEach(() => { + pausable = new PausableSimulator(); + }); + + describe('when not paused', () => { + it('should not be paused in initial state', () => { + expect(pausable.isPaused()).toBeFalsy(); + }); + + it('should throw when calling assertPaused', () => { + expect(() => { + pausable.assertPaused(); + }).toThrow('Pausable: not paused'); + }); + + it('should not throw when calling assertNotPaused', () => { + pausable.assertNotPaused(); + }); + + it('should pause from unpaused state', () => { + pausable.pause(); + expect(pausable.isPaused()).toBeTruthy(); + }); + + it('should throw when unpausing in an unpaused state', () => { + expect(() => { + pausable.unpause(); + }).toThrow('Pausable: not paused'); + }); + }); + + describe('when paused', () => { + beforeEach(() => { + pausable.pause(); + }); + + it('should not throw when calling assertPaused', () => { + pausable.assertPaused(); + }); + + it('should throw when calling assertNotPaused', () => { + expect(() => { + pausable.assertNotPaused(); + }).toThrow('Pausable: paused'); + }); + + it('should unpause from paused state', () => { + pausable.unpause(); + expect(pausable.isPaused()).toBeFalsy(); + }); + + it('should throw when pausing in an paused state', () => { + expect(() => { + pausable.pause(); + }).toThrow('Pausable: paused'); + }); + }); + + describe('Multiple Operations', () => { + it('should handle pause → unpause → pause sequence', () => { + pausable.pause(); + expect(pausable.isPaused()).toBeTruthy(); + + pausable.unpause(); + expect(pausable.isPaused()).toBeFalsy(); + + pausable.pause(); + expect(pausable.isPaused()).toBeTruthy(); + }); + }); +}); diff --git a/contracts/pausable/contract/src/test/types/index.ts b/contracts/pausable/contract/src/test/types/index.ts new file mode 100644 index 00000000..db642b5e --- /dev/null +++ b/contracts/pausable/contract/src/test/types/index.ts @@ -0,0 +1 @@ +export type { IContractSimulator } from './test'; diff --git a/contracts/pausable/contract/src/test/types/test.ts b/contracts/pausable/contract/src/test/types/test.ts new file mode 100644 index 00000000..10fb6c98 --- /dev/null +++ b/contracts/pausable/contract/src/test/types/test.ts @@ -0,0 +1,23 @@ +import type { CircuitContext, ContractState } from '@midnight-ntwrk/compact-runtime'; + +/** + * Generic interface for mock contract implementations. + * @template P - The type of the contract's private state. + * @template L - The type of the contract's ledger (public state). + */ +export interface IContractSimulator { + /** The contract's deployed address. */ + readonly contractAddress: string; + + /** The current circuit context. */ + circuitContext: CircuitContext

; + + /** Retrieves the current ledger state. */ + getCurrentPublicState(): L; + + /** Retrieves the current private state. */ + getCurrentPrivateState(): P; + + /** Retrieves the current contract state. */ + getCurrentContractState(): ContractState; +} diff --git a/contracts/pausable/contract/src/test/utils/index.ts b/contracts/pausable/contract/src/test/utils/index.ts new file mode 100644 index 00000000..14e02ef2 --- /dev/null +++ b/contracts/pausable/contract/src/test/utils/index.ts @@ -0,0 +1 @@ +export { useCircuitContext as circuitContext } from './test'; diff --git a/contracts/pausable/contract/src/test/utils/test.ts b/contracts/pausable/contract/src/test/utils/test.ts new file mode 100644 index 00000000..5a9e5837 --- /dev/null +++ b/contracts/pausable/contract/src/test/utils/test.ts @@ -0,0 +1,67 @@ +import { + type CircuitContext, + type CoinPublicKey, + type ContractAddress, + type ContractState, + QueryContext, + emptyZswapLocalState, +} from '@midnight-ntwrk/compact-runtime'; +import type { IContractSimulator } from '../types'; + +/** + * Constructs a `CircuitContext` from the given state and sender information. + * + * This is typically used at runtime to provide the necessary context + * for executing circuits, including contract state, private state, + * sender identity, and transaction data. + * + * @template P - The type of the contract's private state. + * @param privateState - The current private state of the contract. + * @param contractState - The full contract state, including public and private data. + * @param sender - The public key of the sender (used in the circuit). + * @param contractAddress - The address of the deployed contract. + * @returns A fully populated `CircuitContext` for circuit execution. + * @todo TODO: Move this utility to a generic package for broader reuse across contracts. + */ +export function useCircuitContext

( + privateState: P, + contractState: ContractState, + sender: CoinPublicKey, + contractAddress: ContractAddress, +): CircuitContext

{ + return { + originalState: contractState, + currentPrivateState: privateState, + transactionContext: new QueryContext(contractState.data, contractAddress), + currentZswapLocalState: emptyZswapLocalState(sender), + }; +} + +/** + * Prepares a new `CircuitContext` using the given sender and contract. + * + * Useful for mocking or updating the circuit context with a custom sender. + * + * @template P - The type of the contract's private state. + * @template L - The type of the contract's ledger (public state). + * @template C - The specific type of the contract implementing `MockContract`. + * @param contract - The contract instance implementing `MockContract`. + * @param sender - The public key to set as the sender in the new circuit context. + * @returns A new `CircuitContext` with the sender and updated context values. + * @todo TODO: Move this utility to a generic package for broader reuse across contracts. + */ +export function useCircuitContextSender>( + contract: C, + sender: CoinPublicKey, +): CircuitContext

{ + const currentPrivateState = contract.getCurrentPrivateState(); + const originalState = contract.getCurrentContractState(); + const contractAddress = contract.contractAddress; + + return { + originalState, + currentPrivateState, + transactionContext: new QueryContext(originalState.data, contractAddress), + currentZswapLocalState: emptyZswapLocalState(sender), + }; +} diff --git a/contracts/pausable/contract/src/witnesses/PausableWitnesses.ts b/contracts/pausable/contract/src/witnesses/PausableWitnesses.ts new file mode 100644 index 00000000..70ecc08f --- /dev/null +++ b/contracts/pausable/contract/src/witnesses/PausableWitnesses.ts @@ -0,0 +1,3 @@ +// This is how we type an empty object. +export type PausablePrivateState = Record; +export const PausableWitnesses = {}; diff --git a/contracts/pausable/contract/src/witnesses/index.ts b/contracts/pausable/contract/src/witnesses/index.ts new file mode 100644 index 00000000..0f2d99f6 --- /dev/null +++ b/contracts/pausable/contract/src/witnesses/index.ts @@ -0,0 +1,2 @@ +export * from '../artifacts/pausable/contract/index.cjs'; +export * from './PausableWitnesses'; diff --git a/contracts/pausable/contract/tsconfig.build.json b/contracts/pausable/contract/tsconfig.build.json new file mode 100644 index 00000000..f1132509 --- /dev/null +++ b/contracts/pausable/contract/tsconfig.build.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["src/test/**/*.ts"], + "compilerOptions": {} +} diff --git a/contracts/pausable/contract/tsconfig.json b/contracts/pausable/contract/tsconfig.json new file mode 100644 index 00000000..3e90b0a9 --- /dev/null +++ b/contracts/pausable/contract/tsconfig.json @@ -0,0 +1,21 @@ +{ + "include": ["src/**/*.ts"], + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "declaration": true, + "lib": ["ESNext"], + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "node", + "allowJs": true, + "forceConsistentCasingInFileNames": true, + "noImplicitAny": true, + "strict": true, + "isolatedModules": true, + "sourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "skipLibCheck": true + } +} diff --git a/package.json b/package.json index 18f45583..b5e3e08e 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "workspaces": [ "compact", "contracts/initializable/*", + "contracts/pausable/*", "contracts/utils/*" ], "scripts": { diff --git a/yarn.lock b/yarn.lock index e4e5b0dc..de27b20b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1096,6 +1096,17 @@ __metadata: languageName: unknown linkType: soft +"@openzeppelin-midnight-contracts/pausable-contract@workspace:contracts/pausable/contract": + version: 0.0.0-use.local + resolution: "@openzeppelin-midnight-contracts/pausable-contract@workspace:contracts/pausable/contract" + dependencies: + "@midnight-ntwrk/compact": "workspace:*" + eslint: "npm:^8.52.0" + jest: "npm:^29.7.0" + typescript: "npm:^5.2.2" + languageName: unknown + linkType: soft + "@openzeppelin-midnight-contracts/utils-contract@workspace:contracts/utils/contract": version: 0.0.0-use.local resolution: "@openzeppelin-midnight-contracts/utils-contract@workspace:contracts/utils/contract" From 63cb131e55ae81a4d3a2f60fb0a8202cad3fff47 Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 6 Apr 2025 16:17:46 -0500 Subject: [PATCH 02/17] update repo structure --- .../contract/src/witnesses/index.ts | 2 - contracts/pausable/contract/jest.config.ts | 24 ------- contracts/pausable/contract/package.json | 29 -------- .../pausable/contract/src/test/types/index.ts | 1 - .../pausable/contract/src/test/utils/index.ts | 1 - .../pausable/contract/src/test/utils/test.ts | 67 ------------------- .../pausable/contract/src/witnesses/index.ts | 2 - .../contract => security}/.eslintignore | 0 .../contract => security}/.eslintrc.cjs | 0 .../contract => security}/jest.config.ts | 0 .../contract => security}/js-resolver.cjs | 0 .../contract => security}/package.json | 4 +- .../src/Initializable.compact | 0 .../src/MockInitializable.compact | 0 .../src/MockPausable.compact | 0 .../src/Pausable.compact | 0 .../src/test/initializable.test.ts | 3 +- .../src/test/pausable.test.ts | 2 +- .../simulators}/InitializableSimulator.ts | 6 +- .../src/test/simulators}/PausableSimulator.ts | 6 +- .../src/test/types/index.ts | 0 .../src/test/types/test.ts | 0 .../src/test/utils/index.ts | 0 .../src/test/utils/test.ts | 0 .../src/witnesses/InitializableWitnesses.ts | 0 .../src/witnesses/PausableWitnesses.ts | 0 contracts/security/src/witnesses/index.ts | 2 + .../contract => security}/tsconfig.build.json | 0 .../contract => security}/tsconfig.json | 0 .../contract => utils}/.eslintignore | 0 .../contract => utils}/.eslintrc.cjs | 0 contracts/utils/contract/.eslintignore | 1 - contracts/utils/contract/.eslintrc.cjs | 30 --------- contracts/utils/contract/js-resolver.cjs | 16 ----- .../utils/contract/src/test/types/test.ts | 23 ------- contracts/utils/contract/tsconfig.build.json | 5 -- contracts/utils/contract/tsconfig.json | 21 ------ contracts/utils/{contract => }/jest.config.ts | 0 .../contract => utils}/js-resolver.cjs | 0 contracts/utils/{contract => }/package.json | 0 .../{contract => }/src/MockUtils.compact | 0 .../utils/{contract => }/src/Utils.compact | 0 .../{contract => }/src/test/UtilsSimulator.ts | 0 .../{contract => }/src/test/types/index.ts | 0 .../contract => utils}/src/test/types/test.ts | 0 .../{contract => }/src/test/utils.test.ts | 0 .../{contract => }/src/test/utils/address.ts | 0 .../{contract => }/src/test/utils/index.ts | 0 .../{contract => }/src/test/utils/test.ts | 0 .../src/witnesses/UtilsWitnesses.ts | 0 .../{contract => }/src/witnesses/index.ts | 0 .../contract => utils}/tsconfig.build.json | 0 .../contract => utils}/tsconfig.json | 0 package.json | 5 +- yarn.lock | 19 ++---- 55 files changed, 19 insertions(+), 250 deletions(-) delete mode 100644 contracts/initializable/contract/src/witnesses/index.ts delete mode 100644 contracts/pausable/contract/jest.config.ts delete mode 100644 contracts/pausable/contract/package.json delete mode 100644 contracts/pausable/contract/src/test/types/index.ts delete mode 100644 contracts/pausable/contract/src/test/utils/index.ts delete mode 100644 contracts/pausable/contract/src/test/utils/test.ts delete mode 100644 contracts/pausable/contract/src/witnesses/index.ts rename contracts/{initializable/contract => security}/.eslintignore (100%) rename contracts/{initializable/contract => security}/.eslintrc.cjs (100%) rename contracts/{initializable/contract => security}/jest.config.ts (100%) rename contracts/{initializable/contract => security}/js-resolver.cjs (100%) rename contracts/{initializable/contract => security}/package.json (89%) rename contracts/{initializable/contract => security}/src/Initializable.compact (100%) rename contracts/{initializable/contract => security}/src/MockInitializable.compact (100%) rename contracts/{pausable/contract => security}/src/MockPausable.compact (100%) rename contracts/{pausable/contract => security}/src/Pausable.compact (100%) rename contracts/{initializable/contract => security}/src/test/initializable.test.ts (93%) rename contracts/{pausable/contract => security}/src/test/pausable.test.ts (96%) rename contracts/{initializable/contract/src/test => security/src/test/simulators}/InitializableSimulator.ts (95%) rename contracts/{pausable/contract/src/test => security/src/test/simulators}/PausableSimulator.ts (94%) rename contracts/{initializable/contract => security}/src/test/types/index.ts (100%) rename contracts/{initializable/contract => security}/src/test/types/test.ts (100%) rename contracts/{initializable/contract => security}/src/test/utils/index.ts (100%) rename contracts/{initializable/contract => security}/src/test/utils/test.ts (100%) rename contracts/{initializable/contract => security}/src/witnesses/InitializableWitnesses.ts (100%) rename contracts/{pausable/contract => security}/src/witnesses/PausableWitnesses.ts (100%) create mode 100644 contracts/security/src/witnesses/index.ts rename contracts/{initializable/contract => security}/tsconfig.build.json (100%) rename contracts/{initializable/contract => security}/tsconfig.json (100%) rename contracts/{pausable/contract => utils}/.eslintignore (100%) rename contracts/{pausable/contract => utils}/.eslintrc.cjs (100%) delete mode 100644 contracts/utils/contract/.eslintignore delete mode 100644 contracts/utils/contract/.eslintrc.cjs delete mode 100644 contracts/utils/contract/js-resolver.cjs delete mode 100644 contracts/utils/contract/src/test/types/test.ts delete mode 100644 contracts/utils/contract/tsconfig.build.json delete mode 100644 contracts/utils/contract/tsconfig.json rename contracts/utils/{contract => }/jest.config.ts (100%) rename contracts/{pausable/contract => utils}/js-resolver.cjs (100%) rename contracts/utils/{contract => }/package.json (100%) rename contracts/utils/{contract => }/src/MockUtils.compact (100%) rename contracts/utils/{contract => }/src/Utils.compact (100%) rename contracts/utils/{contract => }/src/test/UtilsSimulator.ts (100%) rename contracts/utils/{contract => }/src/test/types/index.ts (100%) rename contracts/{pausable/contract => utils}/src/test/types/test.ts (100%) rename contracts/utils/{contract => }/src/test/utils.test.ts (100%) rename contracts/utils/{contract => }/src/test/utils/address.ts (100%) rename contracts/utils/{contract => }/src/test/utils/index.ts (100%) rename contracts/utils/{contract => }/src/test/utils/test.ts (100%) rename contracts/utils/{contract => }/src/witnesses/UtilsWitnesses.ts (100%) rename contracts/utils/{contract => }/src/witnesses/index.ts (100%) rename contracts/{pausable/contract => utils}/tsconfig.build.json (100%) rename contracts/{pausable/contract => utils}/tsconfig.json (100%) diff --git a/contracts/initializable/contract/src/witnesses/index.ts b/contracts/initializable/contract/src/witnesses/index.ts deleted file mode 100644 index d27dd4c3..00000000 --- a/contracts/initializable/contract/src/witnesses/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../artifacts/initializable/contract/index.cjs'; -export * from './InitializableWitnesses'; diff --git a/contracts/pausable/contract/jest.config.ts b/contracts/pausable/contract/jest.config.ts deleted file mode 100644 index db2dbd5f..00000000 --- a/contracts/pausable/contract/jest.config.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { Config } from "@jest/types"; - -const config: Config.InitialOptions = { - preset: "ts-jest/presets/default-esm", - testEnvironment: "node", - verbose: true, - roots: [""], - modulePaths: [""], - passWithNoTests: false, - testMatch: ["**/*.test.ts"], - extensionsToTreatAsEsm: [".ts"], - collectCoverage: true, - resolver: '/js-resolver.cjs', - coverageThreshold: { - global: {}, - }, - reporters: [ - "default", - ["jest-junit", { outputDirectory: "reports", outputName: "report.xml" }], - ["jest-html-reporters", { publicPath: "reports", filename: "report.html" }], - ], -}; - -export default config; diff --git a/contracts/pausable/contract/package.json b/contracts/pausable/contract/package.json deleted file mode 100644 index 33814780..00000000 --- a/contracts/pausable/contract/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "@openzeppelin-midnight-contracts/pausable-contract", - "type": "module", - "main": "dist/index.js", - "module": "dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "require": "./dist/index.js", - "import": "./dist/index.js", - "default": "./dist/index.js" - } - }, - "scripts": { - "compact": "find src -name '*.compact' -exec sh -c 'run-compactc \"{}\" \"src/artifacts/$(basename \"{}\" .compact)\"' \\;", - "test": "NODE_OPTIONS=--experimental-vm-modules jest", - "prepack": "yarn build", - "build": "rm -rf dist && tsc --project tsconfig.build.json && cp -Rf ./src/artifacts ./dist/artifacts && cp ./src/Pausable.compact ./dist", - "lint": "eslint src", - "typecheck": "tsc -p tsconfig.json --noEmit" - }, - "devDependencies": { - "@midnight-ntwrk/compact": "workspace:*", - "eslint": "^8.52.0", - "jest": "^29.7.0", - "typescript": "^5.2.2" - } -} diff --git a/contracts/pausable/contract/src/test/types/index.ts b/contracts/pausable/contract/src/test/types/index.ts deleted file mode 100644 index db642b5e..00000000 --- a/contracts/pausable/contract/src/test/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export type { IContractSimulator } from './test'; diff --git a/contracts/pausable/contract/src/test/utils/index.ts b/contracts/pausable/contract/src/test/utils/index.ts deleted file mode 100644 index 14e02ef2..00000000 --- a/contracts/pausable/contract/src/test/utils/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { useCircuitContext as circuitContext } from './test'; diff --git a/contracts/pausable/contract/src/test/utils/test.ts b/contracts/pausable/contract/src/test/utils/test.ts deleted file mode 100644 index 5a9e5837..00000000 --- a/contracts/pausable/contract/src/test/utils/test.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { - type CircuitContext, - type CoinPublicKey, - type ContractAddress, - type ContractState, - QueryContext, - emptyZswapLocalState, -} from '@midnight-ntwrk/compact-runtime'; -import type { IContractSimulator } from '../types'; - -/** - * Constructs a `CircuitContext` from the given state and sender information. - * - * This is typically used at runtime to provide the necessary context - * for executing circuits, including contract state, private state, - * sender identity, and transaction data. - * - * @template P - The type of the contract's private state. - * @param privateState - The current private state of the contract. - * @param contractState - The full contract state, including public and private data. - * @param sender - The public key of the sender (used in the circuit). - * @param contractAddress - The address of the deployed contract. - * @returns A fully populated `CircuitContext` for circuit execution. - * @todo TODO: Move this utility to a generic package for broader reuse across contracts. - */ -export function useCircuitContext

( - privateState: P, - contractState: ContractState, - sender: CoinPublicKey, - contractAddress: ContractAddress, -): CircuitContext

{ - return { - originalState: contractState, - currentPrivateState: privateState, - transactionContext: new QueryContext(contractState.data, contractAddress), - currentZswapLocalState: emptyZswapLocalState(sender), - }; -} - -/** - * Prepares a new `CircuitContext` using the given sender and contract. - * - * Useful for mocking or updating the circuit context with a custom sender. - * - * @template P - The type of the contract's private state. - * @template L - The type of the contract's ledger (public state). - * @template C - The specific type of the contract implementing `MockContract`. - * @param contract - The contract instance implementing `MockContract`. - * @param sender - The public key to set as the sender in the new circuit context. - * @returns A new `CircuitContext` with the sender and updated context values. - * @todo TODO: Move this utility to a generic package for broader reuse across contracts. - */ -export function useCircuitContextSender>( - contract: C, - sender: CoinPublicKey, -): CircuitContext

{ - const currentPrivateState = contract.getCurrentPrivateState(); - const originalState = contract.getCurrentContractState(); - const contractAddress = contract.contractAddress; - - return { - originalState, - currentPrivateState, - transactionContext: new QueryContext(originalState.data, contractAddress), - currentZswapLocalState: emptyZswapLocalState(sender), - }; -} diff --git a/contracts/pausable/contract/src/witnesses/index.ts b/contracts/pausable/contract/src/witnesses/index.ts deleted file mode 100644 index 0f2d99f6..00000000 --- a/contracts/pausable/contract/src/witnesses/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../artifacts/pausable/contract/index.cjs'; -export * from './PausableWitnesses'; diff --git a/contracts/initializable/contract/.eslintignore b/contracts/security/.eslintignore similarity index 100% rename from contracts/initializable/contract/.eslintignore rename to contracts/security/.eslintignore diff --git a/contracts/initializable/contract/.eslintrc.cjs b/contracts/security/.eslintrc.cjs similarity index 100% rename from contracts/initializable/contract/.eslintrc.cjs rename to contracts/security/.eslintrc.cjs diff --git a/contracts/initializable/contract/jest.config.ts b/contracts/security/jest.config.ts similarity index 100% rename from contracts/initializable/contract/jest.config.ts rename to contracts/security/jest.config.ts diff --git a/contracts/initializable/contract/js-resolver.cjs b/contracts/security/js-resolver.cjs similarity index 100% rename from contracts/initializable/contract/js-resolver.cjs rename to contracts/security/js-resolver.cjs diff --git a/contracts/initializable/contract/package.json b/contracts/security/package.json similarity index 89% rename from contracts/initializable/contract/package.json rename to contracts/security/package.json index a04f1d3a..b5867553 100644 --- a/contracts/initializable/contract/package.json +++ b/contracts/security/package.json @@ -1,5 +1,5 @@ { - "name": "@openzeppelin-midnight-contracts/initializable-contract", + "name": "@openzeppelin-midnight-contracts/security", "type": "module", "main": "dist/index.js", "module": "dist/index.js", @@ -16,7 +16,7 @@ "compact": "find src -name '*.compact' -exec sh -c 'run-compactc \"{}\" \"src/artifacts/$(basename \"{}\" .compact)\"' \\;", "test": "NODE_OPTIONS=--experimental-vm-modules jest", "prepack": "yarn build", - "build": "rm -rf dist && tsc --project tsconfig.build.json && cp -Rf ./src/artifacts ./dist/artifacts && cp ./src/Initializable.compact ./dist", + "build": "rm -rf dist && tsc --project tsconfig.build.json && cp -Rf ./src/artifacts ./dist/artifacts && cp ./src/Initializable.compact ./src/Pausable.compact ./dist", "lint": "eslint src", "typecheck": "tsc -p tsconfig.json --noEmit" }, diff --git a/contracts/initializable/contract/src/Initializable.compact b/contracts/security/src/Initializable.compact similarity index 100% rename from contracts/initializable/contract/src/Initializable.compact rename to contracts/security/src/Initializable.compact diff --git a/contracts/initializable/contract/src/MockInitializable.compact b/contracts/security/src/MockInitializable.compact similarity index 100% rename from contracts/initializable/contract/src/MockInitializable.compact rename to contracts/security/src/MockInitializable.compact diff --git a/contracts/pausable/contract/src/MockPausable.compact b/contracts/security/src/MockPausable.compact similarity index 100% rename from contracts/pausable/contract/src/MockPausable.compact rename to contracts/security/src/MockPausable.compact diff --git a/contracts/pausable/contract/src/Pausable.compact b/contracts/security/src/Pausable.compact similarity index 100% rename from contracts/pausable/contract/src/Pausable.compact rename to contracts/security/src/Pausable.compact diff --git a/contracts/initializable/contract/src/test/initializable.test.ts b/contracts/security/src/test/initializable.test.ts similarity index 93% rename from contracts/initializable/contract/src/test/initializable.test.ts rename to contracts/security/src/test/initializable.test.ts index 15ee059c..d5d74e7a 100644 --- a/contracts/initializable/contract/src/test/initializable.test.ts +++ b/contracts/security/src/test/initializable.test.ts @@ -1,7 +1,8 @@ import { it, describe, expect } from '@jest/globals'; -import { InitializableSimulator } from './InitializableSimulator.js'; +import { InitializableSimulator } from './simulators/InitializableSimulator.js'; import { Initializable_STATE as STATE } from '../artifacts/MockInitializable/contract/index.cjs'; + const contract = new InitializableSimulator(); describe('Initializable', () => { diff --git a/contracts/pausable/contract/src/test/pausable.test.ts b/contracts/security/src/test/pausable.test.ts similarity index 96% rename from contracts/pausable/contract/src/test/pausable.test.ts rename to contracts/security/src/test/pausable.test.ts index a4e62ae9..32184931 100644 --- a/contracts/pausable/contract/src/test/pausable.test.ts +++ b/contracts/security/src/test/pausable.test.ts @@ -1,5 +1,5 @@ import { it, describe, expect } from '@jest/globals'; -import { PausableSimulator } from './PausableSimulator.js'; +import { PausableSimulator } from './simulators/PausableSimulator.js'; let pausable: PausableSimulator; diff --git a/contracts/initializable/contract/src/test/InitializableSimulator.ts b/contracts/security/src/test/simulators/InitializableSimulator.ts similarity index 95% rename from contracts/initializable/contract/src/test/InitializableSimulator.ts rename to contracts/security/src/test/simulators/InitializableSimulator.ts index 89402a19..ff37a29a 100644 --- a/contracts/initializable/contract/src/test/InitializableSimulator.ts +++ b/contracts/security/src/test/simulators/InitializableSimulator.ts @@ -1,7 +1,7 @@ import { type CircuitContext, type ContractState, QueryContext, sampleContractAddress, constructorContext } from '@midnight-ntwrk/compact-runtime'; -import { Contract as MockInitializable, type Ledger, ledger } from '../artifacts/MockInitializable/contract/index.cjs'; -import type { IContractSimulator } from './types'; -import { InitializablePrivateState, InitializableWitnesses } from '../witnesses'; +import { Contract as MockInitializable, type Ledger, ledger } from '../../artifacts/MockInitializable/contract/index.cjs'; +import type { IContractSimulator } from '../types'; +import { InitializablePrivateState, InitializableWitnesses } from '../../witnesses'; /** * @description A simulator implementation of an utils contract for testing purposes. diff --git a/contracts/pausable/contract/src/test/PausableSimulator.ts b/contracts/security/src/test/simulators/PausableSimulator.ts similarity index 94% rename from contracts/pausable/contract/src/test/PausableSimulator.ts rename to contracts/security/src/test/simulators/PausableSimulator.ts index eebce672..052a7e58 100644 --- a/contracts/pausable/contract/src/test/PausableSimulator.ts +++ b/contracts/security/src/test/simulators/PausableSimulator.ts @@ -1,7 +1,7 @@ import { type CircuitContext, type ContractState, QueryContext, sampleContractAddress, constructorContext } from '@midnight-ntwrk/compact-runtime'; -import { Contract as MockPausable, type Ledger, ledger } from '../artifacts/MockPausable/contract/index.cjs'; -import type { IContractSimulator } from './types'; -import { PausablePrivateState, PausableWitnesses } from '../witnesses'; +import { Contract as MockPausable, type Ledger, ledger } from '../../artifacts/MockPausable/contract/index.cjs'; +import type { IContractSimulator } from '../types'; +import { PausablePrivateState, PausableWitnesses } from '../../witnesses'; /** * @description A simulator implementation of an utils contract for testing purposes. diff --git a/contracts/initializable/contract/src/test/types/index.ts b/contracts/security/src/test/types/index.ts similarity index 100% rename from contracts/initializable/contract/src/test/types/index.ts rename to contracts/security/src/test/types/index.ts diff --git a/contracts/initializable/contract/src/test/types/test.ts b/contracts/security/src/test/types/test.ts similarity index 100% rename from contracts/initializable/contract/src/test/types/test.ts rename to contracts/security/src/test/types/test.ts diff --git a/contracts/initializable/contract/src/test/utils/index.ts b/contracts/security/src/test/utils/index.ts similarity index 100% rename from contracts/initializable/contract/src/test/utils/index.ts rename to contracts/security/src/test/utils/index.ts diff --git a/contracts/initializable/contract/src/test/utils/test.ts b/contracts/security/src/test/utils/test.ts similarity index 100% rename from contracts/initializable/contract/src/test/utils/test.ts rename to contracts/security/src/test/utils/test.ts diff --git a/contracts/initializable/contract/src/witnesses/InitializableWitnesses.ts b/contracts/security/src/witnesses/InitializableWitnesses.ts similarity index 100% rename from contracts/initializable/contract/src/witnesses/InitializableWitnesses.ts rename to contracts/security/src/witnesses/InitializableWitnesses.ts diff --git a/contracts/pausable/contract/src/witnesses/PausableWitnesses.ts b/contracts/security/src/witnesses/PausableWitnesses.ts similarity index 100% rename from contracts/pausable/contract/src/witnesses/PausableWitnesses.ts rename to contracts/security/src/witnesses/PausableWitnesses.ts diff --git a/contracts/security/src/witnesses/index.ts b/contracts/security/src/witnesses/index.ts new file mode 100644 index 00000000..694bbd84 --- /dev/null +++ b/contracts/security/src/witnesses/index.ts @@ -0,0 +1,2 @@ +export { type InitializablePrivateState, InitializableWitnesses } from './InitializableWitnesses'; +export { type PausablePrivateState, PausableWitnesses } from './PausableWitnesses'; diff --git a/contracts/initializable/contract/tsconfig.build.json b/contracts/security/tsconfig.build.json similarity index 100% rename from contracts/initializable/contract/tsconfig.build.json rename to contracts/security/tsconfig.build.json diff --git a/contracts/initializable/contract/tsconfig.json b/contracts/security/tsconfig.json similarity index 100% rename from contracts/initializable/contract/tsconfig.json rename to contracts/security/tsconfig.json diff --git a/contracts/pausable/contract/.eslintignore b/contracts/utils/.eslintignore similarity index 100% rename from contracts/pausable/contract/.eslintignore rename to contracts/utils/.eslintignore diff --git a/contracts/pausable/contract/.eslintrc.cjs b/contracts/utils/.eslintrc.cjs similarity index 100% rename from contracts/pausable/contract/.eslintrc.cjs rename to contracts/utils/.eslintrc.cjs diff --git a/contracts/utils/contract/.eslintignore b/contracts/utils/contract/.eslintignore deleted file mode 100644 index 327555cd..00000000 --- a/contracts/utils/contract/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -src/artifacts diff --git a/contracts/utils/contract/.eslintrc.cjs b/contracts/utils/contract/.eslintrc.cjs deleted file mode 100644 index 581f1d49..00000000 --- a/contracts/utils/contract/.eslintrc.cjs +++ /dev/null @@ -1,30 +0,0 @@ -module.exports = { - env: { - browser: true, - es2021: true, - node: true, - jest: true, - }, - extends: [ - 'standard-with-typescript', - 'plugin:prettier/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - ], - overrides: [], - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: ['tsconfig.json'], - }, - rules: { - '@typescript-eslint/no-misused-promises': 'off', // https://github.com/typescript-eslint/typescript-eslint/issues/5807 - '@typescript-eslint/no-floating-promises': 'warn', - '@typescript-eslint/promise-function-async': 'off', - '@typescript-eslint/no-redeclare': 'off', - '@typescript-eslint/no-invalid-void-type': 'off', - '@typescript-eslint/no-unsafe-call': 'off', - '@typescript-eslint/no-unsafe-member-access': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/consistent-type-definitions': 'off' - }, -}; diff --git a/contracts/utils/contract/js-resolver.cjs b/contracts/utils/contract/js-resolver.cjs deleted file mode 100644 index cc9ed285..00000000 --- a/contracts/utils/contract/js-resolver.cjs +++ /dev/null @@ -1,16 +0,0 @@ -const jsResolver = (path, options) => { - const jsExtRegex = /\.js$/i - const resolver = options.defaultResolver - if (jsExtRegex.test(path) && !options.basedir.includes('node_modules') && !path.includes('node_modules')) { - const newPath = path.replace(jsExtRegex, '.ts'); - try { - return resolver(newPath, options) - } catch { - // use default resolver - } - } - - return resolver(path, options) -} - -module.exports = jsResolver diff --git a/contracts/utils/contract/src/test/types/test.ts b/contracts/utils/contract/src/test/types/test.ts deleted file mode 100644 index 10fb6c98..00000000 --- a/contracts/utils/contract/src/test/types/test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { CircuitContext, ContractState } from '@midnight-ntwrk/compact-runtime'; - -/** - * Generic interface for mock contract implementations. - * @template P - The type of the contract's private state. - * @template L - The type of the contract's ledger (public state). - */ -export interface IContractSimulator { - /** The contract's deployed address. */ - readonly contractAddress: string; - - /** The current circuit context. */ - circuitContext: CircuitContext

; - - /** Retrieves the current ledger state. */ - getCurrentPublicState(): L; - - /** Retrieves the current private state. */ - getCurrentPrivateState(): P; - - /** Retrieves the current contract state. */ - getCurrentContractState(): ContractState; -} diff --git a/contracts/utils/contract/tsconfig.build.json b/contracts/utils/contract/tsconfig.build.json deleted file mode 100644 index f1132509..00000000 --- a/contracts/utils/contract/tsconfig.build.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "./tsconfig.json", - "exclude": ["src/test/**/*.ts"], - "compilerOptions": {} -} diff --git a/contracts/utils/contract/tsconfig.json b/contracts/utils/contract/tsconfig.json deleted file mode 100644 index 3e90b0a9..00000000 --- a/contracts/utils/contract/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "include": ["src/**/*.ts"], - "compilerOptions": { - "rootDir": "src", - "outDir": "dist", - "declaration": true, - "lib": ["ESNext"], - "target": "ES2022", - "module": "ESNext", - "moduleResolution": "node", - "allowJs": true, - "forceConsistentCasingInFileNames": true, - "noImplicitAny": true, - "strict": true, - "isolatedModules": true, - "sourceMap": true, - "resolveJsonModule": true, - "esModuleInterop": true, - "skipLibCheck": true - } -} diff --git a/contracts/utils/contract/jest.config.ts b/contracts/utils/jest.config.ts similarity index 100% rename from contracts/utils/contract/jest.config.ts rename to contracts/utils/jest.config.ts diff --git a/contracts/pausable/contract/js-resolver.cjs b/contracts/utils/js-resolver.cjs similarity index 100% rename from contracts/pausable/contract/js-resolver.cjs rename to contracts/utils/js-resolver.cjs diff --git a/contracts/utils/contract/package.json b/contracts/utils/package.json similarity index 100% rename from contracts/utils/contract/package.json rename to contracts/utils/package.json diff --git a/contracts/utils/contract/src/MockUtils.compact b/contracts/utils/src/MockUtils.compact similarity index 100% rename from contracts/utils/contract/src/MockUtils.compact rename to contracts/utils/src/MockUtils.compact diff --git a/contracts/utils/contract/src/Utils.compact b/contracts/utils/src/Utils.compact similarity index 100% rename from contracts/utils/contract/src/Utils.compact rename to contracts/utils/src/Utils.compact diff --git a/contracts/utils/contract/src/test/UtilsSimulator.ts b/contracts/utils/src/test/UtilsSimulator.ts similarity index 100% rename from contracts/utils/contract/src/test/UtilsSimulator.ts rename to contracts/utils/src/test/UtilsSimulator.ts diff --git a/contracts/utils/contract/src/test/types/index.ts b/contracts/utils/src/test/types/index.ts similarity index 100% rename from contracts/utils/contract/src/test/types/index.ts rename to contracts/utils/src/test/types/index.ts diff --git a/contracts/pausable/contract/src/test/types/test.ts b/contracts/utils/src/test/types/test.ts similarity index 100% rename from contracts/pausable/contract/src/test/types/test.ts rename to contracts/utils/src/test/types/test.ts diff --git a/contracts/utils/contract/src/test/utils.test.ts b/contracts/utils/src/test/utils.test.ts similarity index 100% rename from contracts/utils/contract/src/test/utils.test.ts rename to contracts/utils/src/test/utils.test.ts diff --git a/contracts/utils/contract/src/test/utils/address.ts b/contracts/utils/src/test/utils/address.ts similarity index 100% rename from contracts/utils/contract/src/test/utils/address.ts rename to contracts/utils/src/test/utils/address.ts diff --git a/contracts/utils/contract/src/test/utils/index.ts b/contracts/utils/src/test/utils/index.ts similarity index 100% rename from contracts/utils/contract/src/test/utils/index.ts rename to contracts/utils/src/test/utils/index.ts diff --git a/contracts/utils/contract/src/test/utils/test.ts b/contracts/utils/src/test/utils/test.ts similarity index 100% rename from contracts/utils/contract/src/test/utils/test.ts rename to contracts/utils/src/test/utils/test.ts diff --git a/contracts/utils/contract/src/witnesses/UtilsWitnesses.ts b/contracts/utils/src/witnesses/UtilsWitnesses.ts similarity index 100% rename from contracts/utils/contract/src/witnesses/UtilsWitnesses.ts rename to contracts/utils/src/witnesses/UtilsWitnesses.ts diff --git a/contracts/utils/contract/src/witnesses/index.ts b/contracts/utils/src/witnesses/index.ts similarity index 100% rename from contracts/utils/contract/src/witnesses/index.ts rename to contracts/utils/src/witnesses/index.ts diff --git a/contracts/pausable/contract/tsconfig.build.json b/contracts/utils/tsconfig.build.json similarity index 100% rename from contracts/pausable/contract/tsconfig.build.json rename to contracts/utils/tsconfig.build.json diff --git a/contracts/pausable/contract/tsconfig.json b/contracts/utils/tsconfig.json similarity index 100% rename from contracts/pausable/contract/tsconfig.json rename to contracts/utils/tsconfig.json diff --git a/package.json b/package.json index b5e3e08e..2040dac3 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,8 @@ "packageManager": "yarn@4.1.0", "workspaces": [ "compact", - "contracts/initializable/*", - "contracts/pausable/*", - "contracts/utils/*" + "contracts/security", + "contracts/utils/" ], "scripts": { "compact": "turbo run compact", diff --git a/yarn.lock b/yarn.lock index de27b20b..dd62ba53 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1085,9 +1085,9 @@ __metadata: languageName: node linkType: hard -"@openzeppelin-midnight-contracts/initializable-contract@workspace:contracts/initializable/contract": +"@openzeppelin-midnight-contracts/security@workspace:contracts/security": version: 0.0.0-use.local - resolution: "@openzeppelin-midnight-contracts/initializable-contract@workspace:contracts/initializable/contract" + resolution: "@openzeppelin-midnight-contracts/security@workspace:contracts/security" dependencies: "@midnight-ntwrk/compact": "workspace:*" eslint: "npm:^8.52.0" @@ -1096,20 +1096,9 @@ __metadata: languageName: unknown linkType: soft -"@openzeppelin-midnight-contracts/pausable-contract@workspace:contracts/pausable/contract": +"@openzeppelin-midnight-contracts/utils-contract@workspace:contracts/utils": version: 0.0.0-use.local - resolution: "@openzeppelin-midnight-contracts/pausable-contract@workspace:contracts/pausable/contract" - dependencies: - "@midnight-ntwrk/compact": "workspace:*" - eslint: "npm:^8.52.0" - jest: "npm:^29.7.0" - typescript: "npm:^5.2.2" - languageName: unknown - linkType: soft - -"@openzeppelin-midnight-contracts/utils-contract@workspace:contracts/utils/contract": - version: 0.0.0-use.local - resolution: "@openzeppelin-midnight-contracts/utils-contract@workspace:contracts/utils/contract" + resolution: "@openzeppelin-midnight-contracts/utils-contract@workspace:contracts/utils" dependencies: "@midnight-ntwrk/compact": "workspace:*" eslint: "npm:^8.52.0" From 9f6feb7885de271423b309dd9383b5fa434b1c1d Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 6 Apr 2025 16:30:00 -0500 Subject: [PATCH 03/17] move mock contracts to mocks dir --- contracts/security/src/{ => mocks}/MockInitializable.compact | 2 +- contracts/security/src/{ => mocks}/MockPausable.compact | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename contracts/security/src/{ => mocks}/MockInitializable.compact (85%) rename contracts/security/src/{ => mocks}/MockPausable.compact (91%) diff --git a/contracts/security/src/MockInitializable.compact b/contracts/security/src/mocks/MockInitializable.compact similarity index 85% rename from contracts/security/src/MockInitializable.compact rename to contracts/security/src/mocks/MockInitializable.compact index d670f6d9..a3c5bb23 100644 --- a/contracts/security/src/MockInitializable.compact +++ b/contracts/security/src/mocks/MockInitializable.compact @@ -1,7 +1,7 @@ pragma language_version >= 0.14.0; import CompactStandardLibrary; -import Initializable prefix Initializable_; +import "../Initializable" prefix Initializable_; export { Initializable_state, Initializable_STATE }; diff --git a/contracts/security/src/MockPausable.compact b/contracts/security/src/mocks/MockPausable.compact similarity index 91% rename from contracts/security/src/MockPausable.compact rename to contracts/security/src/mocks/MockPausable.compact index 1a90349b..e0e0ddc4 100644 --- a/contracts/security/src/MockPausable.compact +++ b/contracts/security/src/mocks/MockPausable.compact @@ -1,7 +1,7 @@ pragma language_version >= 0.14.0; import CompactStandardLibrary; -import Pausable prefix Pausable_; +import "../Pausable" prefix Pausable_; export { Pausable__isPaused }; From f404601793a28b5698f486b855a1fafbd145ea1b Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 6 Apr 2025 16:33:51 -0500 Subject: [PATCH 04/17] fix initializable tests --- .../security/src/test/initializable.test.ts | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/contracts/security/src/test/initializable.test.ts b/contracts/security/src/test/initializable.test.ts index d5d74e7a..01dcedf0 100644 --- a/contracts/security/src/test/initializable.test.ts +++ b/contracts/security/src/test/initializable.test.ts @@ -2,32 +2,35 @@ import { it, describe, expect } from '@jest/globals'; import { InitializableSimulator } from './simulators/InitializableSimulator.js'; import { Initializable_STATE as STATE } from '../artifacts/MockInitializable/contract/index.cjs'; - -const contract = new InitializableSimulator(); +let initializable: InitializableSimulator; describe('Initializable', () => { + beforeEach(() => { + initializable = new InitializableSimulator(); + }); + it('should generate the initial ledger state deterministically', () => { - const contract2 = new InitializableSimulator(); - expect(contract.getCurrentPublicState()).toEqual(contract2.getCurrentPublicState()); + const initializable2 = new InitializableSimulator(); + expect(initializable.getCurrentPublicState()).toEqual(initializable2.getCurrentPublicState()); }); describe('initialize', () => { it('should not be initialized', () => { - expect(contract.isInitialized()).toEqual(false); - expect(contract.getCurrentPublicState().initializableState).toEqual(STATE.uninitialized); + expect(initializable.isInitialized()).toEqual(false); + expect(initializable.getCurrentPublicState().initializableState).toEqual(STATE.uninitialized); }); it('should initialize', () => { - contract.initialize(); - expect(contract.isInitialized()).toEqual(true); - expect(contract.getCurrentPublicState().initializableState).toEqual(STATE.initialized); + initializable.initialize(); + expect(initializable.isInitialized()).toEqual(true); + expect(initializable.getCurrentPublicState().initializableState).toEqual(STATE.initialized); }); }); it('should fail when re-initialized', () => { expect(() => { - contract.initialize(); - contract.initialize(); + initializable.initialize(); + initializable.initialize(); }).toThrow('Contract already initialized'); }); }); From f299daab201abfa75da8f0abfe74e89dce4d0a9d Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 6 Apr 2025 19:23:13 -0500 Subject: [PATCH 05/17] move mocks to test --- .../security/src/{ => test}/mocks/MockInitializable.compact | 2 +- contracts/security/src/{ => test}/mocks/MockPausable.compact | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename contracts/security/src/{ => test}/mocks/MockInitializable.compact (84%) rename contracts/security/src/{ => test}/mocks/MockPausable.compact (91%) diff --git a/contracts/security/src/mocks/MockInitializable.compact b/contracts/security/src/test/mocks/MockInitializable.compact similarity index 84% rename from contracts/security/src/mocks/MockInitializable.compact rename to contracts/security/src/test/mocks/MockInitializable.compact index a3c5bb23..80fcca2e 100644 --- a/contracts/security/src/mocks/MockInitializable.compact +++ b/contracts/security/src/test/mocks/MockInitializable.compact @@ -1,7 +1,7 @@ pragma language_version >= 0.14.0; import CompactStandardLibrary; -import "../Initializable" prefix Initializable_; +import "../../Initializable" prefix Initializable_; export { Initializable_state, Initializable_STATE }; diff --git a/contracts/security/src/mocks/MockPausable.compact b/contracts/security/src/test/mocks/MockPausable.compact similarity index 91% rename from contracts/security/src/mocks/MockPausable.compact rename to contracts/security/src/test/mocks/MockPausable.compact index e0e0ddc4..deab3f15 100644 --- a/contracts/security/src/mocks/MockPausable.compact +++ b/contracts/security/src/test/mocks/MockPausable.compact @@ -1,7 +1,7 @@ pragma language_version >= 0.14.0; import CompactStandardLibrary; -import "../Pausable" prefix Pausable_; +import "../../Pausable" prefix Pausable_; export { Pausable__isPaused }; From d4006958a502ce2b3bd9db0511f86248e3d6a769 Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 6 Apr 2025 19:28:32 -0500 Subject: [PATCH 06/17] add comments to pausable simulator --- .../src/test/simulators/PausableSimulator.ts | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/contracts/security/src/test/simulators/PausableSimulator.ts b/contracts/security/src/test/simulators/PausableSimulator.ts index 052a7e58..4c526a00 100644 --- a/contracts/security/src/test/simulators/PausableSimulator.ts +++ b/contracts/security/src/test/simulators/PausableSimulator.ts @@ -70,27 +70,43 @@ export class PausableSimulator return this.circuitContext.originalState; } - /** - * @description Initializes the state. - * @returns None. + /** + * @description Returns true if the contract is paused, and false otherwise. + * @returns True if paused. */ public isPaused() { return this.contract.impureCircuits.isPaused(this.circuitContext).result; } - public pause() { - this.circuitContext = this.contract.impureCircuits.pause(this.circuitContext).context; - } - - public unpause() { - this.circuitContext = this.contract.impureCircuits.unpause(this.circuitContext).context; - } - + /** + * @description Makes a circuit only callable when the contract is paused. + * @returns None. + */ public assertPaused() { this.circuitContext = this.contract.impureCircuits.assertPaused(this.circuitContext).context; } + /** + * @description Makes a circuit only callable when the contract is not paused. + * @returns None. + */ public assertNotPaused() { this.circuitContext = this.contract.impureCircuits.assertNotPaused(this.circuitContext).context; } + + /** + * @description Triggers a stopped state. + * @returns None. + */ + public pause() { + this.circuitContext = this.contract.impureCircuits.pause(this.circuitContext).context; + } + + /** + * @description Lifts the pause on the contract. + * @returns None. + */ + public unpause() { + this.circuitContext = this.contract.impureCircuits.unpause(this.circuitContext).context; + } } From 06bdc4a9ef2f545e668729e6cdf805ceec0eefc2 Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 6 Apr 2025 19:29:04 -0500 Subject: [PATCH 07/17] add return type to isPaused --- contracts/security/src/test/simulators/PausableSimulator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/security/src/test/simulators/PausableSimulator.ts b/contracts/security/src/test/simulators/PausableSimulator.ts index 4c526a00..2103a3c7 100644 --- a/contracts/security/src/test/simulators/PausableSimulator.ts +++ b/contracts/security/src/test/simulators/PausableSimulator.ts @@ -74,7 +74,7 @@ export class PausableSimulator * @description Returns true if the contract is paused, and false otherwise. * @returns True if paused. */ - public isPaused() { + public isPaused(): boolean { return this.contract.impureCircuits.isPaused(this.circuitContext).result; } From 930cda0a0d3e84fdf183626715f8514431df3c41 Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 6 Apr 2025 19:30:18 -0500 Subject: [PATCH 08/17] add line --- contracts/security/src/test/mocks/MockPausable.compact | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/security/src/test/mocks/MockPausable.compact b/contracts/security/src/test/mocks/MockPausable.compact index deab3f15..a564fbe6 100644 --- a/contracts/security/src/test/mocks/MockPausable.compact +++ b/contracts/security/src/test/mocks/MockPausable.compact @@ -23,4 +23,4 @@ export circuit pause(): [] { export circuit unpause(): [] { return Pausable__unpause(); -} \ No newline at end of file +} From 0f6f9f46943a05db16bebd1644122964fe6a4ad8 Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 6 Apr 2025 19:39:54 -0500 Subject: [PATCH 09/17] fix comment --- contracts/security/src/Pausable.compact | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/security/src/Pausable.compact b/contracts/security/src/Pausable.compact index 92685f24..8e9eba5b 100644 --- a/contracts/security/src/Pausable.compact +++ b/contracts/security/src/Pausable.compact @@ -2,7 +2,7 @@ pragma language_version >= 0.14.0; /** - * @module Pausable. + * @module Pausable * @description Pausable allows the implementing contract to implement * an emergency stop mechanism. Only circuits that call `assertPaused` * or `assertNotPaused` will be affected by this mechanism. From 55f5966d7b88ff77c8d6373168a7e85624df6bf7 Mon Sep 17 00:00:00 2001 From: andrew Date: Sun, 6 Apr 2025 19:42:23 -0500 Subject: [PATCH 10/17] simplify build script --- contracts/security/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/security/package.json b/contracts/security/package.json index b5867553..47b3793a 100644 --- a/contracts/security/package.json +++ b/contracts/security/package.json @@ -16,7 +16,7 @@ "compact": "find src -name '*.compact' -exec sh -c 'run-compactc \"{}\" \"src/artifacts/$(basename \"{}\" .compact)\"' \\;", "test": "NODE_OPTIONS=--experimental-vm-modules jest", "prepack": "yarn build", - "build": "rm -rf dist && tsc --project tsconfig.build.json && cp -Rf ./src/artifacts ./dist/artifacts && cp ./src/Initializable.compact ./src/Pausable.compact ./dist", + "build": "rm -rf dist && tsc --project tsconfig.build.json && cp -Rf ./src/artifacts ./dist/artifacts && cp ./src/{Initializable,Pausable}.compact ./dist", "lint": "eslint src", "typecheck": "tsc -p tsconfig.json --noEmit" }, From f72387cc524c7d3986ef67df733d8cfc70f02596 Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 7 Apr 2025 00:29:51 -0500 Subject: [PATCH 11/17] improve simulator export --- contracts/security/src/test/initializable.test.ts | 2 +- contracts/security/src/test/pausable.test.ts | 2 +- contracts/security/src/test/simulators/index.ts | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 contracts/security/src/test/simulators/index.ts diff --git a/contracts/security/src/test/initializable.test.ts b/contracts/security/src/test/initializable.test.ts index 01dcedf0..5e689b45 100644 --- a/contracts/security/src/test/initializable.test.ts +++ b/contracts/security/src/test/initializable.test.ts @@ -1,5 +1,5 @@ import { it, describe, expect } from '@jest/globals'; -import { InitializableSimulator } from './simulators/InitializableSimulator.js'; +import { InitializableSimulator } from './simulators'; import { Initializable_STATE as STATE } from '../artifacts/MockInitializable/contract/index.cjs'; let initializable: InitializableSimulator; diff --git a/contracts/security/src/test/pausable.test.ts b/contracts/security/src/test/pausable.test.ts index 32184931..1c5316cf 100644 --- a/contracts/security/src/test/pausable.test.ts +++ b/contracts/security/src/test/pausable.test.ts @@ -1,5 +1,5 @@ import { it, describe, expect } from '@jest/globals'; -import { PausableSimulator } from './simulators/PausableSimulator.js'; +import { PausableSimulator } from './simulators'; let pausable: PausableSimulator; diff --git a/contracts/security/src/test/simulators/index.ts b/contracts/security/src/test/simulators/index.ts new file mode 100644 index 00000000..7a1b217a --- /dev/null +++ b/contracts/security/src/test/simulators/index.ts @@ -0,0 +1,2 @@ +export { InitializableSimulator } from './InitializableSimulator'; +export { PausableSimulator } from './PausableSimulator'; From 2aa2eeaddaf2ea8e6d0363f00a01d3e0b9540256 Mon Sep 17 00:00:00 2001 From: Andrew Fleming Date: Mon, 7 Apr 2025 00:36:53 -0500 Subject: [PATCH 12/17] fix test file name --- .../src/test/{initializable.test.ts => Initializable.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contracts/security/src/test/{initializable.test.ts => Initializable.test.ts} (100%) diff --git a/contracts/security/src/test/initializable.test.ts b/contracts/security/src/test/Initializable.test.ts similarity index 100% rename from contracts/security/src/test/initializable.test.ts rename to contracts/security/src/test/Initializable.test.ts From 41b532259341f406762d706989b8c0754684f6f2 Mon Sep 17 00:00:00 2001 From: Andrew Fleming Date: Mon, 7 Apr 2025 00:37:06 -0500 Subject: [PATCH 13/17] Rename pausable.test.ts to Pausable.test.ts --- .../security/src/test/{pausable.test.ts => Pausable.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contracts/security/src/test/{pausable.test.ts => Pausable.test.ts} (100%) diff --git a/contracts/security/src/test/pausable.test.ts b/contracts/security/src/test/Pausable.test.ts similarity index 100% rename from contracts/security/src/test/pausable.test.ts rename to contracts/security/src/test/Pausable.test.ts From 6cb173375856ecffdd7aa65709e7eeb5ae2ac6c5 Mon Sep 17 00:00:00 2001 From: Iskander Date: Thu, 17 Apr 2025 18:44:52 +0100 Subject: [PATCH 14/17] chore: initializable in pausable style (#34) --- contracts/security/src/Initializable.compact | 29 +++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/contracts/security/src/Initializable.compact b/contracts/security/src/Initializable.compact index 648f7670..910f53ff 100644 --- a/contracts/security/src/Initializable.compact +++ b/contracts/security/src/Initializable.compact @@ -5,12 +5,10 @@ pragma language_version >= 0.14.0; * @module Initializable * @description Initializable provides a simple mechanism that mimics the functionality of a constructor. */ -module Initializable{ +module Initializable { import CompactStandardLibrary; - export enum STATE { uninitialized, initialized } - - export ledger state: STATE; + export ledger _isInitialized: Boolean; /** * @description Initializes the state thus ensuring the calling circuit can only be called once. @@ -18,16 +16,27 @@ module Initializable{ * @returns None. */ export circuit initialize(): [] { - assert state == STATE.uninitialized "Contract already initialized"; - state = STATE.initialized; + assertNotInitialized(); + _isInitialized = true; + } + + /** + * @description Asserts that the contract has been initialized, throwing an error if not. + * + * @returns None. + * @throws Will throw "Initializable: contract not initialized" if the contract is not initialized. + */ + export circuit assertInitialized(): [] { + assert _isInitialized "Initializable: contract not initialized"; } /** - * @description Returns true if the state is initialized. + * @description Asserts that the contract has not been initialized, throwing an error if it has. * - * @returns {Boolean} - whether the contract has been initialized. + * @returns None. + * @throws Will throw "Initializable: Contract already initialized" if the contract is already initialized. */ - export circuit isInitialized(): Boolean { - return (state == STATE.initialized); + export circuit assertNotInitialized(): [] { + assert !_isInitialized "Initializable: Contract already initialized"; } } From 560352cccf95db14a44d199a33a4e3731d1eca5f Mon Sep 17 00:00:00 2001 From: andrew Date: Thu, 17 Apr 2025 13:26:02 -0500 Subject: [PATCH 15/17] move initializable and pausable to utils/ --- contracts/initializable/.eslintignore | 1 - contracts/initializable/.eslintrc.cjs | 30 ------- contracts/initializable/jest.config.ts | 28 ------ contracts/initializable/js-resolver.cjs | 16 ---- contracts/initializable/package.json | 29 ------ .../initializable/src/Initializable.compact | 33 ------- .../src/test/initializable.test.ts | 32 ------- .../initializable/src/test/types/index.ts | 1 - .../initializable/src/test/types/test.ts | 23 ----- .../initializable/src/test/utils/index.ts | 1 - .../initializable/src/test/utils/test.ts | 67 -------------- .../initializable/src/witnesses/index.ts | 2 - contracts/initializable/tsconfig.build.json | 5 -- contracts/initializable/tsconfig.json | 21 ----- contracts/security/.eslintignore | 1 - contracts/security/.eslintrc.cjs | 30 ------- contracts/security/jest.config.ts | 28 ------ contracts/security/js-resolver.cjs | 16 ---- contracts/security/package.json | 29 ------ .../src/test/mocks/MockInitializable.compact | 14 --- .../test/simulators/InitializableSimulator.ts | 88 ------------------- contracts/security/src/test/types/index.ts | 1 - contracts/security/src/test/types/test.ts | 23 ----- contracts/security/src/test/utils/index.ts | 1 - contracts/security/src/test/utils/test.ts | 67 -------------- .../src/witnesses/InitializableWitnesses.ts | 3 - contracts/security/src/witnesses/index.ts | 2 - contracts/security/tsconfig.build.json | 5 -- contracts/security/tsconfig.json | 21 ----- contracts/utils/package.json | 2 +- .../src/Initializable.compact | 2 +- .../{security => utils}/src/Pausable.compact | 0 .../src/test/Initializable.test.ts | 26 +++--- .../src/test/Pausable.test.ts | 0 .../src/test/mocks}/MockInitializable.compact | 6 +- .../src/test/mocks/MockPausable.compact | 0 .../src/{ => test/mocks}/MockUtils.compact | 2 +- .../simulators}/InitializableSimulator.ts | 6 +- .../src/test/simulators/PausableSimulator.ts | 0 .../test/{ => simulators}/UtilsSimulator.ts | 6 +- .../src/test/simulators/index.ts | 2 + contracts/utils/src/test/utils.test.ts | 2 +- .../src/witnesses/InitializableWitnesses.ts | 0 .../src/witnesses/PausableWitnesses.ts | 0 contracts/utils/src/witnesses/index.ts | 2 + 45 files changed, 28 insertions(+), 646 deletions(-) delete mode 100644 contracts/initializable/.eslintignore delete mode 100644 contracts/initializable/.eslintrc.cjs delete mode 100644 contracts/initializable/jest.config.ts delete mode 100644 contracts/initializable/js-resolver.cjs delete mode 100644 contracts/initializable/package.json delete mode 100644 contracts/initializable/src/Initializable.compact delete mode 100644 contracts/initializable/src/test/initializable.test.ts delete mode 100644 contracts/initializable/src/test/types/index.ts delete mode 100644 contracts/initializable/src/test/types/test.ts delete mode 100644 contracts/initializable/src/test/utils/index.ts delete mode 100644 contracts/initializable/src/test/utils/test.ts delete mode 100644 contracts/initializable/src/witnesses/index.ts delete mode 100644 contracts/initializable/tsconfig.build.json delete mode 100644 contracts/initializable/tsconfig.json delete mode 100644 contracts/security/.eslintignore delete mode 100644 contracts/security/.eslintrc.cjs delete mode 100644 contracts/security/jest.config.ts delete mode 100644 contracts/security/js-resolver.cjs delete mode 100644 contracts/security/package.json delete mode 100644 contracts/security/src/test/mocks/MockInitializable.compact delete mode 100644 contracts/security/src/test/simulators/InitializableSimulator.ts delete mode 100644 contracts/security/src/test/types/index.ts delete mode 100644 contracts/security/src/test/types/test.ts delete mode 100644 contracts/security/src/test/utils/index.ts delete mode 100644 contracts/security/src/test/utils/test.ts delete mode 100644 contracts/security/src/witnesses/InitializableWitnesses.ts delete mode 100644 contracts/security/src/witnesses/index.ts delete mode 100644 contracts/security/tsconfig.build.json delete mode 100644 contracts/security/tsconfig.json rename contracts/{security => utils}/src/Initializable.compact (99%) rename contracts/{security => utils}/src/Pausable.compact (100%) rename contracts/{security => utils}/src/test/Initializable.test.ts (54%) rename contracts/{security => utils}/src/test/Pausable.test.ts (100%) rename contracts/{initializable/src => utils/src/test/mocks}/MockInitializable.compact (58%) rename contracts/{security => utils}/src/test/mocks/MockPausable.compact (100%) rename contracts/utils/src/{ => test/mocks}/MockUtils.compact (89%) rename contracts/{initializable/src/test => utils/src/test/simulators}/InitializableSimulator.ts (95%) rename contracts/{security => utils}/src/test/simulators/PausableSimulator.ts (100%) rename contracts/utils/src/test/{ => simulators}/UtilsSimulator.ts (93%) rename contracts/{security => utils}/src/test/simulators/index.ts (67%) rename contracts/{initializable => utils}/src/witnesses/InitializableWitnesses.ts (100%) rename contracts/{security => utils}/src/witnesses/PausableWitnesses.ts (100%) diff --git a/contracts/initializable/.eslintignore b/contracts/initializable/.eslintignore deleted file mode 100644 index 327555cd..00000000 --- a/contracts/initializable/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -src/artifacts diff --git a/contracts/initializable/.eslintrc.cjs b/contracts/initializable/.eslintrc.cjs deleted file mode 100644 index 581f1d49..00000000 --- a/contracts/initializable/.eslintrc.cjs +++ /dev/null @@ -1,30 +0,0 @@ -module.exports = { - env: { - browser: true, - es2021: true, - node: true, - jest: true, - }, - extends: [ - 'standard-with-typescript', - 'plugin:prettier/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - ], - overrides: [], - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: ['tsconfig.json'], - }, - rules: { - '@typescript-eslint/no-misused-promises': 'off', // https://github.com/typescript-eslint/typescript-eslint/issues/5807 - '@typescript-eslint/no-floating-promises': 'warn', - '@typescript-eslint/promise-function-async': 'off', - '@typescript-eslint/no-redeclare': 'off', - '@typescript-eslint/no-invalid-void-type': 'off', - '@typescript-eslint/no-unsafe-call': 'off', - '@typescript-eslint/no-unsafe-member-access': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/consistent-type-definitions': 'off' - }, -}; diff --git a/contracts/initializable/jest.config.ts b/contracts/initializable/jest.config.ts deleted file mode 100644 index 3cbccc1b..00000000 --- a/contracts/initializable/jest.config.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { Config } from "@jest/types"; - -const config: Config.InitialOptions = { - preset: "ts-jest/presets/default-esm", - testEnvironment: "node", - verbose: true, - roots: [""], - modulePaths: [""], - passWithNoTests: false, - testMatch: ["**/*.test.ts"], - extensionsToTreatAsEsm: [".ts"], - collectCoverage: true, - resolver: '/js-resolver.cjs', - coverageThreshold: { - global: { - branches: 50, - functions: 50, - lines: 50, - }, - }, - reporters: [ - "default", - ["jest-junit", { outputDirectory: "reports", outputName: "report.xml" }], - ["jest-html-reporters", { publicPath: "reports", filename: "report.html" }], - ], -}; - -export default config; diff --git a/contracts/initializable/js-resolver.cjs b/contracts/initializable/js-resolver.cjs deleted file mode 100644 index cc9ed285..00000000 --- a/contracts/initializable/js-resolver.cjs +++ /dev/null @@ -1,16 +0,0 @@ -const jsResolver = (path, options) => { - const jsExtRegex = /\.js$/i - const resolver = options.defaultResolver - if (jsExtRegex.test(path) && !options.basedir.includes('node_modules') && !path.includes('node_modules')) { - const newPath = path.replace(jsExtRegex, '.ts'); - try { - return resolver(newPath, options) - } catch { - // use default resolver - } - } - - return resolver(path, options) -} - -module.exports = jsResolver diff --git a/contracts/initializable/package.json b/contracts/initializable/package.json deleted file mode 100644 index 47b3793a..00000000 --- a/contracts/initializable/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "@openzeppelin-midnight-contracts/security", - "type": "module", - "main": "dist/index.js", - "module": "dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "require": "./dist/index.js", - "import": "./dist/index.js", - "default": "./dist/index.js" - } - }, - "scripts": { - "compact": "find src -name '*.compact' -exec sh -c 'run-compactc \"{}\" \"src/artifacts/$(basename \"{}\" .compact)\"' \\;", - "test": "NODE_OPTIONS=--experimental-vm-modules jest", - "prepack": "yarn build", - "build": "rm -rf dist && tsc --project tsconfig.build.json && cp -Rf ./src/artifacts ./dist/artifacts && cp ./src/{Initializable,Pausable}.compact ./dist", - "lint": "eslint src", - "typecheck": "tsc -p tsconfig.json --noEmit" - }, - "devDependencies": { - "@midnight-ntwrk/compact": "workspace:*", - "eslint": "^8.52.0", - "jest": "^29.7.0", - "typescript": "^5.2.2" - } -} diff --git a/contracts/initializable/src/Initializable.compact b/contracts/initializable/src/Initializable.compact deleted file mode 100644 index 648f7670..00000000 --- a/contracts/initializable/src/Initializable.compact +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma language_version >= 0.14.0; - -/** - * @module Initializable - * @description Initializable provides a simple mechanism that mimics the functionality of a constructor. - */ -module Initializable{ - import CompactStandardLibrary; - - export enum STATE { uninitialized, initialized } - - export ledger state: STATE; - - /** - * @description Initializes the state thus ensuring the calling circuit can only be called once. - * - * @returns None. - */ - export circuit initialize(): [] { - assert state == STATE.uninitialized "Contract already initialized"; - state = STATE.initialized; - } - - /** - * @description Returns true if the state is initialized. - * - * @returns {Boolean} - whether the contract has been initialized. - */ - export circuit isInitialized(): Boolean { - return (state == STATE.initialized); - } -} diff --git a/contracts/initializable/src/test/initializable.test.ts b/contracts/initializable/src/test/initializable.test.ts deleted file mode 100644 index 15ee059c..00000000 --- a/contracts/initializable/src/test/initializable.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { it, describe, expect } from '@jest/globals'; -import { InitializableSimulator } from './InitializableSimulator.js'; -import { Initializable_STATE as STATE } from '../artifacts/MockInitializable/contract/index.cjs'; - -const contract = new InitializableSimulator(); - -describe('Initializable', () => { - it('should generate the initial ledger state deterministically', () => { - const contract2 = new InitializableSimulator(); - expect(contract.getCurrentPublicState()).toEqual(contract2.getCurrentPublicState()); - }); - - describe('initialize', () => { - it('should not be initialized', () => { - expect(contract.isInitialized()).toEqual(false); - expect(contract.getCurrentPublicState().initializableState).toEqual(STATE.uninitialized); - }); - - it('should initialize', () => { - contract.initialize(); - expect(contract.isInitialized()).toEqual(true); - expect(contract.getCurrentPublicState().initializableState).toEqual(STATE.initialized); - }); - }); - - it('should fail when re-initialized', () => { - expect(() => { - contract.initialize(); - contract.initialize(); - }).toThrow('Contract already initialized'); - }); -}); diff --git a/contracts/initializable/src/test/types/index.ts b/contracts/initializable/src/test/types/index.ts deleted file mode 100644 index db642b5e..00000000 --- a/contracts/initializable/src/test/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export type { IContractSimulator } from './test'; diff --git a/contracts/initializable/src/test/types/test.ts b/contracts/initializable/src/test/types/test.ts deleted file mode 100644 index 10fb6c98..00000000 --- a/contracts/initializable/src/test/types/test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { CircuitContext, ContractState } from '@midnight-ntwrk/compact-runtime'; - -/** - * Generic interface for mock contract implementations. - * @template P - The type of the contract's private state. - * @template L - The type of the contract's ledger (public state). - */ -export interface IContractSimulator { - /** The contract's deployed address. */ - readonly contractAddress: string; - - /** The current circuit context. */ - circuitContext: CircuitContext

; - - /** Retrieves the current ledger state. */ - getCurrentPublicState(): L; - - /** Retrieves the current private state. */ - getCurrentPrivateState(): P; - - /** Retrieves the current contract state. */ - getCurrentContractState(): ContractState; -} diff --git a/contracts/initializable/src/test/utils/index.ts b/contracts/initializable/src/test/utils/index.ts deleted file mode 100644 index 14e02ef2..00000000 --- a/contracts/initializable/src/test/utils/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { useCircuitContext as circuitContext } from './test'; diff --git a/contracts/initializable/src/test/utils/test.ts b/contracts/initializable/src/test/utils/test.ts deleted file mode 100644 index 5a9e5837..00000000 --- a/contracts/initializable/src/test/utils/test.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { - type CircuitContext, - type CoinPublicKey, - type ContractAddress, - type ContractState, - QueryContext, - emptyZswapLocalState, -} from '@midnight-ntwrk/compact-runtime'; -import type { IContractSimulator } from '../types'; - -/** - * Constructs a `CircuitContext` from the given state and sender information. - * - * This is typically used at runtime to provide the necessary context - * for executing circuits, including contract state, private state, - * sender identity, and transaction data. - * - * @template P - The type of the contract's private state. - * @param privateState - The current private state of the contract. - * @param contractState - The full contract state, including public and private data. - * @param sender - The public key of the sender (used in the circuit). - * @param contractAddress - The address of the deployed contract. - * @returns A fully populated `CircuitContext` for circuit execution. - * @todo TODO: Move this utility to a generic package for broader reuse across contracts. - */ -export function useCircuitContext

( - privateState: P, - contractState: ContractState, - sender: CoinPublicKey, - contractAddress: ContractAddress, -): CircuitContext

{ - return { - originalState: contractState, - currentPrivateState: privateState, - transactionContext: new QueryContext(contractState.data, contractAddress), - currentZswapLocalState: emptyZswapLocalState(sender), - }; -} - -/** - * Prepares a new `CircuitContext` using the given sender and contract. - * - * Useful for mocking or updating the circuit context with a custom sender. - * - * @template P - The type of the contract's private state. - * @template L - The type of the contract's ledger (public state). - * @template C - The specific type of the contract implementing `MockContract`. - * @param contract - The contract instance implementing `MockContract`. - * @param sender - The public key to set as the sender in the new circuit context. - * @returns A new `CircuitContext` with the sender and updated context values. - * @todo TODO: Move this utility to a generic package for broader reuse across contracts. - */ -export function useCircuitContextSender>( - contract: C, - sender: CoinPublicKey, -): CircuitContext

{ - const currentPrivateState = contract.getCurrentPrivateState(); - const originalState = contract.getCurrentContractState(); - const contractAddress = contract.contractAddress; - - return { - originalState, - currentPrivateState, - transactionContext: new QueryContext(originalState.data, contractAddress), - currentZswapLocalState: emptyZswapLocalState(sender), - }; -} diff --git a/contracts/initializable/src/witnesses/index.ts b/contracts/initializable/src/witnesses/index.ts deleted file mode 100644 index d27dd4c3..00000000 --- a/contracts/initializable/src/witnesses/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../artifacts/initializable/contract/index.cjs'; -export * from './InitializableWitnesses'; diff --git a/contracts/initializable/tsconfig.build.json b/contracts/initializable/tsconfig.build.json deleted file mode 100644 index f1132509..00000000 --- a/contracts/initializable/tsconfig.build.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "./tsconfig.json", - "exclude": ["src/test/**/*.ts"], - "compilerOptions": {} -} diff --git a/contracts/initializable/tsconfig.json b/contracts/initializable/tsconfig.json deleted file mode 100644 index 3e90b0a9..00000000 --- a/contracts/initializable/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "include": ["src/**/*.ts"], - "compilerOptions": { - "rootDir": "src", - "outDir": "dist", - "declaration": true, - "lib": ["ESNext"], - "target": "ES2022", - "module": "ESNext", - "moduleResolution": "node", - "allowJs": true, - "forceConsistentCasingInFileNames": true, - "noImplicitAny": true, - "strict": true, - "isolatedModules": true, - "sourceMap": true, - "resolveJsonModule": true, - "esModuleInterop": true, - "skipLibCheck": true - } -} diff --git a/contracts/security/.eslintignore b/contracts/security/.eslintignore deleted file mode 100644 index 327555cd..00000000 --- a/contracts/security/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -src/artifacts diff --git a/contracts/security/.eslintrc.cjs b/contracts/security/.eslintrc.cjs deleted file mode 100644 index 581f1d49..00000000 --- a/contracts/security/.eslintrc.cjs +++ /dev/null @@ -1,30 +0,0 @@ -module.exports = { - env: { - browser: true, - es2021: true, - node: true, - jest: true, - }, - extends: [ - 'standard-with-typescript', - 'plugin:prettier/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - ], - overrides: [], - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: ['tsconfig.json'], - }, - rules: { - '@typescript-eslint/no-misused-promises': 'off', // https://github.com/typescript-eslint/typescript-eslint/issues/5807 - '@typescript-eslint/no-floating-promises': 'warn', - '@typescript-eslint/promise-function-async': 'off', - '@typescript-eslint/no-redeclare': 'off', - '@typescript-eslint/no-invalid-void-type': 'off', - '@typescript-eslint/no-unsafe-call': 'off', - '@typescript-eslint/no-unsafe-member-access': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/consistent-type-definitions': 'off' - }, -}; diff --git a/contracts/security/jest.config.ts b/contracts/security/jest.config.ts deleted file mode 100644 index 3cbccc1b..00000000 --- a/contracts/security/jest.config.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { Config } from "@jest/types"; - -const config: Config.InitialOptions = { - preset: "ts-jest/presets/default-esm", - testEnvironment: "node", - verbose: true, - roots: [""], - modulePaths: [""], - passWithNoTests: false, - testMatch: ["**/*.test.ts"], - extensionsToTreatAsEsm: [".ts"], - collectCoverage: true, - resolver: '/js-resolver.cjs', - coverageThreshold: { - global: { - branches: 50, - functions: 50, - lines: 50, - }, - }, - reporters: [ - "default", - ["jest-junit", { outputDirectory: "reports", outputName: "report.xml" }], - ["jest-html-reporters", { publicPath: "reports", filename: "report.html" }], - ], -}; - -export default config; diff --git a/contracts/security/js-resolver.cjs b/contracts/security/js-resolver.cjs deleted file mode 100644 index cc9ed285..00000000 --- a/contracts/security/js-resolver.cjs +++ /dev/null @@ -1,16 +0,0 @@ -const jsResolver = (path, options) => { - const jsExtRegex = /\.js$/i - const resolver = options.defaultResolver - if (jsExtRegex.test(path) && !options.basedir.includes('node_modules') && !path.includes('node_modules')) { - const newPath = path.replace(jsExtRegex, '.ts'); - try { - return resolver(newPath, options) - } catch { - // use default resolver - } - } - - return resolver(path, options) -} - -module.exports = jsResolver diff --git a/contracts/security/package.json b/contracts/security/package.json deleted file mode 100644 index 47b3793a..00000000 --- a/contracts/security/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "@openzeppelin-midnight-contracts/security", - "type": "module", - "main": "dist/index.js", - "module": "dist/index.js", - "types": "./dist/index.d.ts", - "exports": { - ".": { - "types": "./dist/index.d.ts", - "require": "./dist/index.js", - "import": "./dist/index.js", - "default": "./dist/index.js" - } - }, - "scripts": { - "compact": "find src -name '*.compact' -exec sh -c 'run-compactc \"{}\" \"src/artifacts/$(basename \"{}\" .compact)\"' \\;", - "test": "NODE_OPTIONS=--experimental-vm-modules jest", - "prepack": "yarn build", - "build": "rm -rf dist && tsc --project tsconfig.build.json && cp -Rf ./src/artifacts ./dist/artifacts && cp ./src/{Initializable,Pausable}.compact ./dist", - "lint": "eslint src", - "typecheck": "tsc -p tsconfig.json --noEmit" - }, - "devDependencies": { - "@midnight-ntwrk/compact": "workspace:*", - "eslint": "^8.52.0", - "jest": "^29.7.0", - "typescript": "^5.2.2" - } -} diff --git a/contracts/security/src/test/mocks/MockInitializable.compact b/contracts/security/src/test/mocks/MockInitializable.compact deleted file mode 100644 index 80fcca2e..00000000 --- a/contracts/security/src/test/mocks/MockInitializable.compact +++ /dev/null @@ -1,14 +0,0 @@ -pragma language_version >= 0.14.0; - -import CompactStandardLibrary; -import "../../Initializable" prefix Initializable_; - -export { Initializable_state, Initializable_STATE }; - -export circuit initialize(): [] { - return Initializable_initialize(); -} - -export circuit isInitialized(): Boolean { - return Initializable_isInitialized(); -} diff --git a/contracts/security/src/test/simulators/InitializableSimulator.ts b/contracts/security/src/test/simulators/InitializableSimulator.ts deleted file mode 100644 index ff37a29a..00000000 --- a/contracts/security/src/test/simulators/InitializableSimulator.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { type CircuitContext, type ContractState, QueryContext, sampleContractAddress, constructorContext } from '@midnight-ntwrk/compact-runtime'; -import { Contract as MockInitializable, type Ledger, ledger } from '../../artifacts/MockInitializable/contract/index.cjs'; -import type { IContractSimulator } from '../types'; -import { InitializablePrivateState, InitializableWitnesses } from '../../witnesses'; - -/** - * @description A simulator implementation of an utils contract for testing purposes. - * @template P - The private state type, fixed to UtilsPrivateState. - * @template L - The ledger type, fixed to Contract.Ledger. - */ -export class InitializableSimulator - implements IContractSimulator -{ - /** @description The underlying contract instance managing contract logic. */ - readonly contract: MockInitializable; - - /** @description The deployed address of the contract. */ - readonly contractAddress: string; - - /** @description The current circuit context, updated by contract operations. */ - circuitContext: CircuitContext; - - /** - * @description Initializes the mock contract. - */ - constructor() { - this.contract = new MockInitializable( - InitializableWitnesses, - ); - const { - currentPrivateState, - currentContractState, - currentZswapLocalState, - } = this.contract.initialState( - constructorContext({}, '0'.repeat(64)) - ); - this.circuitContext = { - currentPrivateState, - currentZswapLocalState, - originalState: currentContractState, - transactionContext: new QueryContext( - currentContractState.data, - sampleContractAddress(), - ), - }; - this.contractAddress = this.circuitContext.transactionContext.address; - } - - /** - * @description Retrieves the current public ledger state of the contract. - * @returns The ledger state as defined by the contract. - */ - public getCurrentPublicState(): Ledger { - return ledger(this.circuitContext.transactionContext.state); - } - - /** - * @description Retrieves the current private state of the contract. - * @returns The private state of type UtilsPrivateState. - */ - public getCurrentPrivateState(): InitializablePrivateState { - return this.circuitContext.currentPrivateState; - } - - /** - * @description Retrieves the current contract state. - * @returns The contract state object. - */ - public getCurrentContractState(): ContractState { - return this.circuitContext.originalState; - } - - /** - * @description Initializes the state. - * @returns None. - */ - public initialize() { - this.circuitContext = this.contract.impureCircuits.initialize(this.circuitContext).context; - } - - /** - * @description Returns true if the state is initialized. - * @returns Whether the contract has been initialized. - */ - public isInitialized(): boolean { - return this.contract.impureCircuits.isInitialized(this.circuitContext).result; - } -} diff --git a/contracts/security/src/test/types/index.ts b/contracts/security/src/test/types/index.ts deleted file mode 100644 index db642b5e..00000000 --- a/contracts/security/src/test/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export type { IContractSimulator } from './test'; diff --git a/contracts/security/src/test/types/test.ts b/contracts/security/src/test/types/test.ts deleted file mode 100644 index 10fb6c98..00000000 --- a/contracts/security/src/test/types/test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { CircuitContext, ContractState } from '@midnight-ntwrk/compact-runtime'; - -/** - * Generic interface for mock contract implementations. - * @template P - The type of the contract's private state. - * @template L - The type of the contract's ledger (public state). - */ -export interface IContractSimulator { - /** The contract's deployed address. */ - readonly contractAddress: string; - - /** The current circuit context. */ - circuitContext: CircuitContext

; - - /** Retrieves the current ledger state. */ - getCurrentPublicState(): L; - - /** Retrieves the current private state. */ - getCurrentPrivateState(): P; - - /** Retrieves the current contract state. */ - getCurrentContractState(): ContractState; -} diff --git a/contracts/security/src/test/utils/index.ts b/contracts/security/src/test/utils/index.ts deleted file mode 100644 index 14e02ef2..00000000 --- a/contracts/security/src/test/utils/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { useCircuitContext as circuitContext } from './test'; diff --git a/contracts/security/src/test/utils/test.ts b/contracts/security/src/test/utils/test.ts deleted file mode 100644 index 5a9e5837..00000000 --- a/contracts/security/src/test/utils/test.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { - type CircuitContext, - type CoinPublicKey, - type ContractAddress, - type ContractState, - QueryContext, - emptyZswapLocalState, -} from '@midnight-ntwrk/compact-runtime'; -import type { IContractSimulator } from '../types'; - -/** - * Constructs a `CircuitContext` from the given state and sender information. - * - * This is typically used at runtime to provide the necessary context - * for executing circuits, including contract state, private state, - * sender identity, and transaction data. - * - * @template P - The type of the contract's private state. - * @param privateState - The current private state of the contract. - * @param contractState - The full contract state, including public and private data. - * @param sender - The public key of the sender (used in the circuit). - * @param contractAddress - The address of the deployed contract. - * @returns A fully populated `CircuitContext` for circuit execution. - * @todo TODO: Move this utility to a generic package for broader reuse across contracts. - */ -export function useCircuitContext

( - privateState: P, - contractState: ContractState, - sender: CoinPublicKey, - contractAddress: ContractAddress, -): CircuitContext

{ - return { - originalState: contractState, - currentPrivateState: privateState, - transactionContext: new QueryContext(contractState.data, contractAddress), - currentZswapLocalState: emptyZswapLocalState(sender), - }; -} - -/** - * Prepares a new `CircuitContext` using the given sender and contract. - * - * Useful for mocking or updating the circuit context with a custom sender. - * - * @template P - The type of the contract's private state. - * @template L - The type of the contract's ledger (public state). - * @template C - The specific type of the contract implementing `MockContract`. - * @param contract - The contract instance implementing `MockContract`. - * @param sender - The public key to set as the sender in the new circuit context. - * @returns A new `CircuitContext` with the sender and updated context values. - * @todo TODO: Move this utility to a generic package for broader reuse across contracts. - */ -export function useCircuitContextSender>( - contract: C, - sender: CoinPublicKey, -): CircuitContext

{ - const currentPrivateState = contract.getCurrentPrivateState(); - const originalState = contract.getCurrentContractState(); - const contractAddress = contract.contractAddress; - - return { - originalState, - currentPrivateState, - transactionContext: new QueryContext(originalState.data, contractAddress), - currentZswapLocalState: emptyZswapLocalState(sender), - }; -} diff --git a/contracts/security/src/witnesses/InitializableWitnesses.ts b/contracts/security/src/witnesses/InitializableWitnesses.ts deleted file mode 100644 index 9d99cd04..00000000 --- a/contracts/security/src/witnesses/InitializableWitnesses.ts +++ /dev/null @@ -1,3 +0,0 @@ -// This is how we type an empty object. -export type InitializablePrivateState = Record; -export const InitializableWitnesses = {}; diff --git a/contracts/security/src/witnesses/index.ts b/contracts/security/src/witnesses/index.ts deleted file mode 100644 index 694bbd84..00000000 --- a/contracts/security/src/witnesses/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { type InitializablePrivateState, InitializableWitnesses } from './InitializableWitnesses'; -export { type PausablePrivateState, PausableWitnesses } from './PausableWitnesses'; diff --git a/contracts/security/tsconfig.build.json b/contracts/security/tsconfig.build.json deleted file mode 100644 index f1132509..00000000 --- a/contracts/security/tsconfig.build.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "./tsconfig.json", - "exclude": ["src/test/**/*.ts"], - "compilerOptions": {} -} diff --git a/contracts/security/tsconfig.json b/contracts/security/tsconfig.json deleted file mode 100644 index 3e90b0a9..00000000 --- a/contracts/security/tsconfig.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "include": ["src/**/*.ts"], - "compilerOptions": { - "rootDir": "src", - "outDir": "dist", - "declaration": true, - "lib": ["ESNext"], - "target": "ES2022", - "module": "ESNext", - "moduleResolution": "node", - "allowJs": true, - "forceConsistentCasingInFileNames": true, - "noImplicitAny": true, - "strict": true, - "isolatedModules": true, - "sourceMap": true, - "resolveJsonModule": true, - "esModuleInterop": true, - "skipLibCheck": true - } -} diff --git a/contracts/utils/package.json b/contracts/utils/package.json index 40c57157..7e21677a 100644 --- a/contracts/utils/package.json +++ b/contracts/utils/package.json @@ -16,7 +16,7 @@ "compact": "find src -name '*.compact' -exec sh -c 'run-compactc \"{}\" \"src/artifacts/$(basename \"{}\" .compact)\"' \\;", "test": "NODE_OPTIONS=--experimental-vm-modules jest", "prepack": "yarn build", - "build": "rm -rf dist && tsc --project tsconfig.build.json && cp -Rf ./src/artifacts ./dist/artifacts && cp ./src/Utils.compact ./dist", + "build": "rm -rf dist && tsc --project tsconfig.build.json && cp -Rf ./src/artifacts ./dist/artifacts && cp ./src/{Initializable,Pausable,Utils}.compact ./dist", "lint": "eslint src", "typecheck": "tsc -p tsconfig.json --noEmit" }, diff --git a/contracts/security/src/Initializable.compact b/contracts/utils/src/Initializable.compact similarity index 99% rename from contracts/security/src/Initializable.compact rename to contracts/utils/src/Initializable.compact index 910f53ff..e078f88d 100644 --- a/contracts/security/src/Initializable.compact +++ b/contracts/utils/src/Initializable.compact @@ -38,5 +38,5 @@ module Initializable { */ export circuit assertNotInitialized(): [] { assert !_isInitialized "Initializable: Contract already initialized"; - } + } } diff --git a/contracts/security/src/Pausable.compact b/contracts/utils/src/Pausable.compact similarity index 100% rename from contracts/security/src/Pausable.compact rename to contracts/utils/src/Pausable.compact diff --git a/contracts/security/src/test/Initializable.test.ts b/contracts/utils/src/test/Initializable.test.ts similarity index 54% rename from contracts/security/src/test/Initializable.test.ts rename to contracts/utils/src/test/Initializable.test.ts index 5e689b45..24f1dd39 100644 --- a/contracts/security/src/test/Initializable.test.ts +++ b/contracts/utils/src/test/Initializable.test.ts @@ -1,6 +1,6 @@ import { it, describe, expect } from '@jest/globals'; +//import { InitializableSimulator } from '../../../security/src/test/simulators'; import { InitializableSimulator } from './simulators'; -import { Initializable_STATE as STATE } from '../artifacts/MockInitializable/contract/index.cjs'; let initializable: InitializableSimulator; @@ -14,18 +14,18 @@ describe('Initializable', () => { expect(initializable.getCurrentPublicState()).toEqual(initializable2.getCurrentPublicState()); }); - describe('initialize', () => { - it('should not be initialized', () => { - expect(initializable.isInitialized()).toEqual(false); - expect(initializable.getCurrentPublicState().initializableState).toEqual(STATE.uninitialized); - }); - - it('should initialize', () => { - initializable.initialize(); - expect(initializable.isInitialized()).toEqual(true); - expect(initializable.getCurrentPublicState().initializableState).toEqual(STATE.initialized); - }); - }); + describe('initialize', () => {}) + // it('should not be initialized', () => { + // expect(initializable.isInitialized()).toEqual(false); + // expect(initializable.getCurrentPublicState().initializableState).toEqual(STATE.uninitialized); + // }); +// + // it('should initialize', () => { + // initializable.initialize(); + // expect(initializable.isInitialized()).toEqual(true); + // expect(initializable.getCurrentPublicState().initializableState).toEqual(STATE.initialized); + // }); + // }); it('should fail when re-initialized', () => { expect(() => { diff --git a/contracts/security/src/test/Pausable.test.ts b/contracts/utils/src/test/Pausable.test.ts similarity index 100% rename from contracts/security/src/test/Pausable.test.ts rename to contracts/utils/src/test/Pausable.test.ts diff --git a/contracts/initializable/src/MockInitializable.compact b/contracts/utils/src/test/mocks/MockInitializable.compact similarity index 58% rename from contracts/initializable/src/MockInitializable.compact rename to contracts/utils/src/test/mocks/MockInitializable.compact index 80fcca2e..c8eeb81b 100644 --- a/contracts/initializable/src/MockInitializable.compact +++ b/contracts/utils/src/test/mocks/MockInitializable.compact @@ -3,12 +3,8 @@ pragma language_version >= 0.14.0; import CompactStandardLibrary; import "../../Initializable" prefix Initializable_; -export { Initializable_state, Initializable_STATE }; +export { Initializable__isInitialized }; export circuit initialize(): [] { return Initializable_initialize(); } - -export circuit isInitialized(): Boolean { - return Initializable_isInitialized(); -} diff --git a/contracts/security/src/test/mocks/MockPausable.compact b/contracts/utils/src/test/mocks/MockPausable.compact similarity index 100% rename from contracts/security/src/test/mocks/MockPausable.compact rename to contracts/utils/src/test/mocks/MockPausable.compact diff --git a/contracts/utils/src/MockUtils.compact b/contracts/utils/src/test/mocks/MockUtils.compact similarity index 89% rename from contracts/utils/src/MockUtils.compact rename to contracts/utils/src/test/mocks/MockUtils.compact index f2263768..dd6507d9 100644 --- a/contracts/utils/src/MockUtils.compact +++ b/contracts/utils/src/test/mocks/MockUtils.compact @@ -4,7 +4,7 @@ pragma language_version >= 0.14.0; import CompactStandardLibrary; -import Utils prefix Utils_; +import "../../Utils" prefix Utils_; export { ZswapCoinPublicKey, ContractAddress, Either }; diff --git a/contracts/initializable/src/test/InitializableSimulator.ts b/contracts/utils/src/test/simulators/InitializableSimulator.ts similarity index 95% rename from contracts/initializable/src/test/InitializableSimulator.ts rename to contracts/utils/src/test/simulators/InitializableSimulator.ts index ff37a29a..e5503674 100644 --- a/contracts/initializable/src/test/InitializableSimulator.ts +++ b/contracts/utils/src/test/simulators/InitializableSimulator.ts @@ -82,7 +82,7 @@ export class InitializableSimulator * @description Returns true if the state is initialized. * @returns Whether the contract has been initialized. */ - public isInitialized(): boolean { - return this.contract.impureCircuits.isInitialized(this.circuitContext).result; - } + //public isInitialized(): boolean { + // return this.contract.impureCircuits.isInitialized(this.circuitContext).result; + //} } diff --git a/contracts/security/src/test/simulators/PausableSimulator.ts b/contracts/utils/src/test/simulators/PausableSimulator.ts similarity index 100% rename from contracts/security/src/test/simulators/PausableSimulator.ts rename to contracts/utils/src/test/simulators/PausableSimulator.ts diff --git a/contracts/utils/src/test/UtilsSimulator.ts b/contracts/utils/src/test/simulators/UtilsSimulator.ts similarity index 93% rename from contracts/utils/src/test/UtilsSimulator.ts rename to contracts/utils/src/test/simulators/UtilsSimulator.ts index c55c802f..e78440b3 100644 --- a/contracts/utils/src/test/UtilsSimulator.ts +++ b/contracts/utils/src/test/simulators/UtilsSimulator.ts @@ -12,9 +12,9 @@ import { Either, ZswapCoinPublicKey, ContractAddress, -} from '../artifacts/MockUtils/contract/index.cjs'; // Combined imports -import type { IContractSimulator } from './types'; -import { UtilsPrivateState, UtilsWitnesses } from '../witnesses'; +} from '../../artifacts/MockUtils/contract/index.cjs'; // Combined imports +import type { IContractSimulator } from '../types'; +import { UtilsPrivateState, UtilsWitnesses } from '../../witnesses'; /** * @description A simulator implementation of an utils contract for testing purposes. diff --git a/contracts/security/src/test/simulators/index.ts b/contracts/utils/src/test/simulators/index.ts similarity index 67% rename from contracts/security/src/test/simulators/index.ts rename to contracts/utils/src/test/simulators/index.ts index 7a1b217a..3d114b3c 100644 --- a/contracts/security/src/test/simulators/index.ts +++ b/contracts/utils/src/test/simulators/index.ts @@ -1,2 +1,4 @@ export { InitializableSimulator } from './InitializableSimulator'; export { PausableSimulator } from './PausableSimulator'; +export { UtilsContractSimulator } from './UtilsSimulator'; + diff --git a/contracts/utils/src/test/utils.test.ts b/contracts/utils/src/test/utils.test.ts index 3f38952b..ea1f5f9b 100644 --- a/contracts/utils/src/test/utils.test.ts +++ b/contracts/utils/src/test/utils.test.ts @@ -1,4 +1,4 @@ -import { UtilsContractSimulator } from './UtilsSimulator'; +import { UtilsContractSimulator } from './simulators'; import * as contractUtils from './utils'; const Z_SOME_KEY = contractUtils.createEitherTestUser('SOME_KEY'); diff --git a/contracts/initializable/src/witnesses/InitializableWitnesses.ts b/contracts/utils/src/witnesses/InitializableWitnesses.ts similarity index 100% rename from contracts/initializable/src/witnesses/InitializableWitnesses.ts rename to contracts/utils/src/witnesses/InitializableWitnesses.ts diff --git a/contracts/security/src/witnesses/PausableWitnesses.ts b/contracts/utils/src/witnesses/PausableWitnesses.ts similarity index 100% rename from contracts/security/src/witnesses/PausableWitnesses.ts rename to contracts/utils/src/witnesses/PausableWitnesses.ts diff --git a/contracts/utils/src/witnesses/index.ts b/contracts/utils/src/witnesses/index.ts index 1c74ba34..41835616 100644 --- a/contracts/utils/src/witnesses/index.ts +++ b/contracts/utils/src/witnesses/index.ts @@ -1,2 +1,4 @@ export * from '../artifacts/utils/contract/index.cjs'; +export * from './InitializableWitnesses.js'; +export * from './PausableWitnesses.js'; export * from './UtilsWitnesses.js'; From ac84eb5c42a639c5d408d950cca3550e3dfae825 Mon Sep 17 00:00:00 2001 From: andrew Date: Thu, 17 Apr 2025 14:02:34 -0500 Subject: [PATCH 16/17] remove barrel files, fix tests --- contracts/erc20/src/test/erc20.test.ts | 16 ++++++++-------- .../erc20/src/test/simulators/ERC20Simulator.ts | 6 +++--- contracts/erc20/src/test/simulators/index.ts | 1 - .../erc20/src/test/types/{index.ts => string.ts} | 2 -- contracts/erc20/src/test/utils/test.ts | 2 +- contracts/erc20/src/witnesses/index.ts | 2 -- contracts/utils/src/test/Initializable.test.ts | 3 +-- contracts/utils/src/test/Pausable.test.ts | 14 +++++++------- .../test/simulators/InitializableSimulator.ts | 4 ++-- .../src/test/simulators/PausableSimulator.ts | 4 ++-- .../utils/src/test/simulators/UtilsSimulator.ts | 6 +++--- contracts/utils/src/test/simulators/index.ts | 4 ---- contracts/utils/src/test/types/index.ts | 1 - contracts/utils/src/test/utils.test.ts | 16 ++++++++-------- contracts/utils/src/test/utils/index.ts | 4 ---- contracts/utils/src/test/utils/test.ts | 2 +- contracts/utils/src/witnesses/index.ts | 4 ---- 17 files changed, 36 insertions(+), 55 deletions(-) delete mode 100644 contracts/erc20/src/test/simulators/index.ts rename contracts/erc20/src/test/types/{index.ts => string.ts} (57%) delete mode 100644 contracts/erc20/src/witnesses/index.ts delete mode 100644 contracts/utils/src/test/simulators/index.ts delete mode 100644 contracts/utils/src/test/types/index.ts delete mode 100644 contracts/utils/src/test/utils/index.ts delete mode 100644 contracts/utils/src/witnesses/index.ts diff --git a/contracts/erc20/src/test/erc20.test.ts b/contracts/erc20/src/test/erc20.test.ts index 939f1c2b..b2e57c8c 100644 --- a/contracts/erc20/src/test/erc20.test.ts +++ b/contracts/erc20/src/test/erc20.test.ts @@ -1,6 +1,6 @@ import { CoinPublicKey } from '@midnight-ntwrk/compact-runtime'; -import { ERC20Simulator } from './simulators'; -import { MaybeString } from './types'; +import { ERC20Simulator } from './simulators/ERC20Simulator'; +import { MaybeString } from './types/string'; import * as utils from './utils'; const NO_STRING: MaybeString = { @@ -96,7 +96,7 @@ describe('ERC20', () => { caller = OWNER; const txSuccess = token.transfer(Z_RECIPIENT, partialAmt, caller); - expect(txSuccess).toBeTruthy(); + expect(txSuccess).toBe(true); expect(token.balanceOf(Z_OWNER)).toEqual(1n); expect(token.balanceOf(Z_RECIPIENT)).toEqual(partialAmt); }); @@ -105,7 +105,7 @@ describe('ERC20', () => { caller = OWNER; const txSuccess = token.transfer(Z_RECIPIENT, AMOUNT, caller); - expect(txSuccess).toBeTruthy(); + expect(txSuccess).toBe(true); expect(token.balanceOf(Z_OWNER)).toEqual(0n); expect(token.balanceOf(Z_RECIPIENT)).toEqual(AMOUNT); }); @@ -137,7 +137,7 @@ describe('ERC20', () => { it('should allow transfer of 0 tokens', () => { const txSuccess = token.transfer(Z_RECIPIENT, 0n, caller); - expect(txSuccess).toBeTruthy(); + expect(txSuccess).toBe(true); expect(token.balanceOf(Z_OWNER)).toEqual(AMOUNT); expect(token.balanceOf(Z_RECIPIENT)).toEqual(0n); }); @@ -233,7 +233,7 @@ describe('ERC20', () => { const partialAmt = AMOUNT - 1n; const txSuccess = token.transferFrom(Z_OWNER, Z_RECIPIENT, partialAmt, caller); - expect(txSuccess).toBeTruthy(); + expect(txSuccess).toBe(true); // Check balances expect(token.balanceOf(Z_OWNER)).toEqual(1n); @@ -246,7 +246,7 @@ describe('ERC20', () => { caller = SPENDER; const txSuccess = token.transferFrom(Z_OWNER, Z_RECIPIENT, AMOUNT, caller); - expect(txSuccess).toBeTruthy(); + expect(txSuccess).toBe(true); // Check balances expect(token.balanceOf(Z_OWNER)).toEqual(0n); @@ -261,7 +261,7 @@ describe('ERC20', () => { caller = SPENDER; const txSuccess = token.transferFrom(Z_OWNER, Z_RECIPIENT, AMOUNT, caller); - expect(txSuccess).toBeTruthy(); + expect(txSuccess).toBe(true); // Check balances expect(token.balanceOf(Z_OWNER)).toEqual(0n); diff --git a/contracts/erc20/src/test/simulators/ERC20Simulator.ts b/contracts/erc20/src/test/simulators/ERC20Simulator.ts index a8e324da..c2f35e5e 100644 --- a/contracts/erc20/src/test/simulators/ERC20Simulator.ts +++ b/contracts/erc20/src/test/simulators/ERC20Simulator.ts @@ -15,9 +15,9 @@ import { ZswapCoinPublicKey, ContractAddress, } from '../../artifacts/MockERC20/contract/index.cjs'; // Combined imports -import { MaybeString } from '../types'; -import type { IContractSimulator } from './../types'; -import { ERC20PrivateState, ERC20Witnesses } from '../../witnesses'; +import { MaybeString } from '../types/string'; +import type { IContractSimulator } from './../types/test'; +import { ERC20PrivateState, ERC20Witnesses } from '../../witnesses/ERC20Witnesses'; /** * @description A simulator implementation of an erc20 contract for testing purposes. diff --git a/contracts/erc20/src/test/simulators/index.ts b/contracts/erc20/src/test/simulators/index.ts deleted file mode 100644 index 134f9c95..00000000 --- a/contracts/erc20/src/test/simulators/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ERC20Simulator } from './ERC20Simulator'; diff --git a/contracts/erc20/src/test/types/index.ts b/contracts/erc20/src/test/types/string.ts similarity index 57% rename from contracts/erc20/src/test/types/index.ts rename to contracts/erc20/src/test/types/string.ts index dac4e694..4735fab2 100644 --- a/contracts/erc20/src/test/types/index.ts +++ b/contracts/erc20/src/test/types/string.ts @@ -1,5 +1,3 @@ -export type { IContractSimulator } from './test'; - export type MaybeString = { is_some: boolean, value: string diff --git a/contracts/erc20/src/test/utils/test.ts b/contracts/erc20/src/test/utils/test.ts index 940ed612..a8840104 100644 --- a/contracts/erc20/src/test/utils/test.ts +++ b/contracts/erc20/src/test/utils/test.ts @@ -6,7 +6,7 @@ import { QueryContext, emptyZswapLocalState, } from '@midnight-ntwrk/compact-runtime'; -import type { IContractSimulator } from '../types'; +import type { IContractSimulator } from '../types/test'; /** * Constructs a `CircuitContext` from the given state and sender information. diff --git a/contracts/erc20/src/witnesses/index.ts b/contracts/erc20/src/witnesses/index.ts deleted file mode 100644 index dc29bf8e..00000000 --- a/contracts/erc20/src/witnesses/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from '../artifacts/erc20/contract/index.cjs'; -export * from './ERC20Witnesses.js'; diff --git a/contracts/utils/src/test/Initializable.test.ts b/contracts/utils/src/test/Initializable.test.ts index 24f1dd39..4cfe4dcc 100644 --- a/contracts/utils/src/test/Initializable.test.ts +++ b/contracts/utils/src/test/Initializable.test.ts @@ -1,6 +1,5 @@ import { it, describe, expect } from '@jest/globals'; -//import { InitializableSimulator } from '../../../security/src/test/simulators'; -import { InitializableSimulator } from './simulators'; +import { InitializableSimulator } from './simulators/InitializableSimulator'; let initializable: InitializableSimulator; diff --git a/contracts/utils/src/test/Pausable.test.ts b/contracts/utils/src/test/Pausable.test.ts index 1c5316cf..fdbb2fac 100644 --- a/contracts/utils/src/test/Pausable.test.ts +++ b/contracts/utils/src/test/Pausable.test.ts @@ -1,5 +1,5 @@ import { it, describe, expect } from '@jest/globals'; -import { PausableSimulator } from './simulators'; +import { PausableSimulator } from './simulators/PausableSimulator'; let pausable: PausableSimulator; @@ -10,7 +10,7 @@ describe('Pausable', () => { describe('when not paused', () => { it('should not be paused in initial state', () => { - expect(pausable.isPaused()).toBeFalsy(); + expect(pausable.isPaused()).toBe(false); }); it('should throw when calling assertPaused', () => { @@ -25,7 +25,7 @@ describe('Pausable', () => { it('should pause from unpaused state', () => { pausable.pause(); - expect(pausable.isPaused()).toBeTruthy(); + expect(pausable.isPaused()).toBe(true); }); it('should throw when unpausing in an unpaused state', () => { @@ -52,7 +52,7 @@ describe('Pausable', () => { it('should unpause from paused state', () => { pausable.unpause(); - expect(pausable.isPaused()).toBeFalsy(); + expect(pausable.isPaused()).toBe(false); }); it('should throw when pausing in an paused state', () => { @@ -65,13 +65,13 @@ describe('Pausable', () => { describe('Multiple Operations', () => { it('should handle pause → unpause → pause sequence', () => { pausable.pause(); - expect(pausable.isPaused()).toBeTruthy(); + expect(pausable.isPaused()).toBe(true); pausable.unpause(); - expect(pausable.isPaused()).toBeFalsy(); + expect(pausable.isPaused()).toBe(false); pausable.pause(); - expect(pausable.isPaused()).toBeTruthy(); + expect(pausable.isPaused()).toBe(true); }); }); }); diff --git a/contracts/utils/src/test/simulators/InitializableSimulator.ts b/contracts/utils/src/test/simulators/InitializableSimulator.ts index e5503674..d6a6f9ad 100644 --- a/contracts/utils/src/test/simulators/InitializableSimulator.ts +++ b/contracts/utils/src/test/simulators/InitializableSimulator.ts @@ -1,7 +1,7 @@ import { type CircuitContext, type ContractState, QueryContext, sampleContractAddress, constructorContext } from '@midnight-ntwrk/compact-runtime'; import { Contract as MockInitializable, type Ledger, ledger } from '../../artifacts/MockInitializable/contract/index.cjs'; -import type { IContractSimulator } from '../types'; -import { InitializablePrivateState, InitializableWitnesses } from '../../witnesses'; +import type { IContractSimulator } from '../types/test'; +import { InitializablePrivateState, InitializableWitnesses } from '../../witnesses/InitializableWitnesses'; /** * @description A simulator implementation of an utils contract for testing purposes. diff --git a/contracts/utils/src/test/simulators/PausableSimulator.ts b/contracts/utils/src/test/simulators/PausableSimulator.ts index 2103a3c7..719a1b61 100644 --- a/contracts/utils/src/test/simulators/PausableSimulator.ts +++ b/contracts/utils/src/test/simulators/PausableSimulator.ts @@ -1,7 +1,7 @@ import { type CircuitContext, type ContractState, QueryContext, sampleContractAddress, constructorContext } from '@midnight-ntwrk/compact-runtime'; import { Contract as MockPausable, type Ledger, ledger } from '../../artifacts/MockPausable/contract/index.cjs'; -import type { IContractSimulator } from '../types'; -import { PausablePrivateState, PausableWitnesses } from '../../witnesses'; +import type { IContractSimulator } from '../types/test'; +import { PausablePrivateState, PausableWitnesses } from '../../witnesses/PausableWitnesses'; /** * @description A simulator implementation of an utils contract for testing purposes. diff --git a/contracts/utils/src/test/simulators/UtilsSimulator.ts b/contracts/utils/src/test/simulators/UtilsSimulator.ts index e78440b3..86304204 100644 --- a/contracts/utils/src/test/simulators/UtilsSimulator.ts +++ b/contracts/utils/src/test/simulators/UtilsSimulator.ts @@ -13,15 +13,15 @@ import { ZswapCoinPublicKey, ContractAddress, } from '../../artifacts/MockUtils/contract/index.cjs'; // Combined imports -import type { IContractSimulator } from '../types'; -import { UtilsPrivateState, UtilsWitnesses } from '../../witnesses'; +import type { IContractSimulator } from '../types/test'; +import { UtilsPrivateState, UtilsWitnesses } from '../../witnesses/UtilsWitnesses'; /** * @description A simulator implementation of an utils contract for testing purposes. * @template P - The private state type, fixed to UtilsPrivateState. * @template L - The ledger type, fixed to Contract.Ledger. */ -export class UtilsContractSimulator +export class UtilsSimulator implements IContractSimulator { /** @description The underlying contract instance managing contract logic. */ diff --git a/contracts/utils/src/test/simulators/index.ts b/contracts/utils/src/test/simulators/index.ts deleted file mode 100644 index 3d114b3c..00000000 --- a/contracts/utils/src/test/simulators/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { InitializableSimulator } from './InitializableSimulator'; -export { PausableSimulator } from './PausableSimulator'; -export { UtilsContractSimulator } from './UtilsSimulator'; - diff --git a/contracts/utils/src/test/types/index.ts b/contracts/utils/src/test/types/index.ts deleted file mode 100644 index db642b5e..00000000 --- a/contracts/utils/src/test/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export type { IContractSimulator } from './test'; diff --git a/contracts/utils/src/test/utils.test.ts b/contracts/utils/src/test/utils.test.ts index ea1f5f9b..43b526da 100644 --- a/contracts/utils/src/test/utils.test.ts +++ b/contracts/utils/src/test/utils.test.ts @@ -1,23 +1,23 @@ -import { UtilsContractSimulator } from './simulators'; -import * as contractUtils from './utils'; +import { UtilsSimulator } from './simulators/UtilsSimulator'; +import * as contractUtils from './utils/address'; const Z_SOME_KEY = contractUtils.createEitherTestUser('SOME_KEY'); const SOME_CONTRACT = contractUtils.createEitherTestContractAddress('SOME_CONTRACT'); -let contract: UtilsContractSimulator; +let contract: UtilsSimulator; describe('Utils', () => { - contract = new UtilsContractSimulator(); + contract = new UtilsSimulator(); describe('isKeyOrAddressZero', () => { it('should return zero for the zero address', () => { - expect(contract.isKeyOrAddressZero(contractUtils.ZERO_KEY)).toBeTruthy(); - expect(contract.isKeyOrAddressZero(contractUtils.ZERO_ADDRESS)).toBeTruthy(); + expect(contract.isKeyOrAddressZero(contractUtils.ZERO_KEY)).toBe(true); + expect(contract.isKeyOrAddressZero(contractUtils.ZERO_ADDRESS)).toBe(true); }); it('should not return zero for nonzero addresses', () => { - expect(contract.isKeyOrAddressZero(Z_SOME_KEY)).toBeFalsy(); - expect(contract.isKeyOrAddressZero(SOME_CONTRACT)).toBeFalsy(); + expect(contract.isKeyOrAddressZero(Z_SOME_KEY)).toBe(false); + expect(contract.isKeyOrAddressZero(SOME_CONTRACT)).toBe(false); }); }); }); diff --git a/contracts/utils/src/test/utils/index.ts b/contracts/utils/src/test/utils/index.ts deleted file mode 100644 index 2668cc79..00000000 --- a/contracts/utils/src/test/utils/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { useCircuitContext as circuitContext } from './test'; -export { - pad, encodeToPK, encodeToAddress, createEitherTestUser, createEitherTestContractAddress, ZERO_KEY, ZERO_ADDRESS -} from './address'; diff --git a/contracts/utils/src/test/utils/test.ts b/contracts/utils/src/test/utils/test.ts index 940ed612..a8840104 100644 --- a/contracts/utils/src/test/utils/test.ts +++ b/contracts/utils/src/test/utils/test.ts @@ -6,7 +6,7 @@ import { QueryContext, emptyZswapLocalState, } from '@midnight-ntwrk/compact-runtime'; -import type { IContractSimulator } from '../types'; +import type { IContractSimulator } from '../types/test'; /** * Constructs a `CircuitContext` from the given state and sender information. diff --git a/contracts/utils/src/witnesses/index.ts b/contracts/utils/src/witnesses/index.ts deleted file mode 100644 index 41835616..00000000 --- a/contracts/utils/src/witnesses/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from '../artifacts/utils/contract/index.cjs'; -export * from './InitializableWitnesses.js'; -export * from './PausableWitnesses.js'; -export * from './UtilsWitnesses.js'; From 2840008f8a2c5d9ed68cc2db65c374c31a38350a Mon Sep 17 00:00:00 2001 From: andrew Date: Thu, 17 Apr 2025 15:17:03 -0500 Subject: [PATCH 17/17] update initializable mock, sim, and tests --- contracts/utils/src/Initializable.compact | 4 +- .../utils/src/test/Initializable.test.ts | 50 ++++++++++++++----- .../src/test/mocks/MockInitializable.compact | 8 +++ .../test/simulators/InitializableSimulator.ts | 24 ++++++--- 4 files changed, 64 insertions(+), 22 deletions(-) diff --git a/contracts/utils/src/Initializable.compact b/contracts/utils/src/Initializable.compact index e078f88d..a31c9bcf 100644 --- a/contracts/utils/src/Initializable.compact +++ b/contracts/utils/src/Initializable.compact @@ -37,6 +37,6 @@ module Initializable { * @throws Will throw "Initializable: Contract already initialized" if the contract is already initialized. */ export circuit assertNotInitialized(): [] { - assert !_isInitialized "Initializable: Contract already initialized"; - } + assert !_isInitialized "Initializable: contract already initialized"; + } } diff --git a/contracts/utils/src/test/Initializable.test.ts b/contracts/utils/src/test/Initializable.test.ts index 4cfe4dcc..5a306087 100644 --- a/contracts/utils/src/test/Initializable.test.ts +++ b/contracts/utils/src/test/Initializable.test.ts @@ -13,23 +13,47 @@ describe('Initializable', () => { expect(initializable.getCurrentPublicState()).toEqual(initializable2.getCurrentPublicState()); }); - describe('initialize', () => {}) - // it('should not be initialized', () => { - // expect(initializable.isInitialized()).toEqual(false); - // expect(initializable.getCurrentPublicState().initializableState).toEqual(STATE.uninitialized); - // }); -// - // it('should initialize', () => { - // initializable.initialize(); - // expect(initializable.isInitialized()).toEqual(true); - // expect(initializable.getCurrentPublicState().initializableState).toEqual(STATE.initialized); - // }); - // }); + describe('initialize', () => { + it('should not be initialized', () => { + expect(initializable.getCurrentPublicState().initializable_IsInitialized).toEqual(false); + }); + + it('should initialize', () => { + initializable.initialize(); + expect(initializable.getCurrentPublicState().initializable_IsInitialized).toEqual(true); + }); + }); it('should fail when re-initialized', () => { expect(() => { initializable.initialize(); initializable.initialize(); - }).toThrow('Contract already initialized'); + }).toThrow('Initializable: contract already initialized'); + }); + + describe('assertInitialized', () => { + it('should fail when not initialized', () => { + expect(() => { + initializable.assertInitialized(); + }).toThrow('Initializable: contract not initialized'); + }); + + it('should not fail when initialized', () => { + initializable.initialize(); + initializable.assertInitialized(); + }); + }); + + describe('assertNotInitialized', () => { + it('should fail when initialized', () => { + initializable.initialize(); + expect(() => { + initializable.assertNotInitialized(); + }).toThrow('Initializable: contract already initialized'); + }); + + it('should not fail when not initialied', () => { + initializable.assertNotInitialized(); + }); }); }); diff --git a/contracts/utils/src/test/mocks/MockInitializable.compact b/contracts/utils/src/test/mocks/MockInitializable.compact index c8eeb81b..e8722a47 100644 --- a/contracts/utils/src/test/mocks/MockInitializable.compact +++ b/contracts/utils/src/test/mocks/MockInitializable.compact @@ -8,3 +8,11 @@ export { Initializable__isInitialized }; export circuit initialize(): [] { return Initializable_initialize(); } + +export circuit assertInitialized(): [] { + return Initializable_assertInitialized(); +} + +export circuit assertNotInitialized(): [] { + return Initializable_assertNotInitialized(); +} diff --git a/contracts/utils/src/test/simulators/InitializableSimulator.ts b/contracts/utils/src/test/simulators/InitializableSimulator.ts index d6a6f9ad..67810eec 100644 --- a/contracts/utils/src/test/simulators/InitializableSimulator.ts +++ b/contracts/utils/src/test/simulators/InitializableSimulator.ts @@ -70,7 +70,7 @@ export class InitializableSimulator return this.circuitContext.originalState; } - /** + /** * @description Initializes the state. * @returns None. */ @@ -78,11 +78,21 @@ export class InitializableSimulator this.circuitContext = this.contract.impureCircuits.initialize(this.circuitContext).context; } - /** - * @description Returns true if the state is initialized. - * @returns Whether the contract has been initialized. + /** + * @description Asserts that the contract has been initialized, throwing an error if not. + * @returns None. + * @throws Will throw "Initializable: contract not initialized" if the contract is not initialized. */ - //public isInitialized(): boolean { - // return this.contract.impureCircuits.isInitialized(this.circuitContext).result; - //} + public assertInitialized() { + return this.contract.impureCircuits.assertInitialized(this.circuitContext).result; + } + + /** + * @description Asserts that the contract has not been initialized, throwing an error if it has. + * @returns None. + * @throws Will throw "Initializable: contract already initialized" if the contract is already initialized. + */ + public assertNotInitialized() { + return this.contract.impureCircuits.assertNotInitialized(this.circuitContext).result; + } }