From a0efe849cd5657ca6f689303cb90ff07dc411445 Mon Sep 17 00:00:00 2001 From: FabienC Date: Mon, 17 Mar 2025 10:57:44 +0200 Subject: [PATCH 01/11] refactor: clean repo and impl base AccessManager --- .../workflows/actions/setup-repo/action.yml | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/actions/setup-repo/action.yml diff --git a/.github/workflows/actions/setup-repo/action.yml b/.github/workflows/actions/setup-repo/action.yml new file mode 100644 index 0000000..3997e6e --- /dev/null +++ b/.github/workflows/actions/setup-repo/action.yml @@ -0,0 +1,31 @@ +name: Setup repo +description: Runs all steps to setup the repo (install node_modules, build, etc...) + +runs: + using: "composite" + steps: + - name: Get bun cache directory path + id: bun-cache-dir-path + shell: bash + run: | + echo "::set-output name=dir::$(bun cache dir)" + echo "::set-output name=version::$(bun -v)" + + - uses: oven-sh/setup-bun@v2 + with: + bun-version: 1.0.26 + + - uses: actions/cache@v4 + id: bun-cache + with: + path: | + **/node_modules + ${{ steps.bun-cache-dir-path.outputs.dir }} + + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} + restore-keys: | + ${{ runner.os }}-bun- + + - name: Install dependencies + shell: bash + run: bun install From cfca75043088fdf4d583f72c00286488965d47fd Mon Sep 17 00:00:00 2001 From: FabienC Date: Wed, 19 Mar 2025 13:50:43 +0200 Subject: [PATCH 02/11] docs: update docs --- CONTRIBUTING.md | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 13 +++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..f7d97e4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,68 @@ +# Contribution Guidelines + +Thanks for your interest in contributing to the Transmuter system! Transmuter is a community built protocol and anyone +is welcome to improve it. + +If you need to get in contact with the repository maintainers, please reach out in the +[#community-dev channel](https://discord.gg/DgFR5T4DbM) of Parallel Discord Server. + +## Types of Contributing + +There are many ways to contribute, but here are a few if you want a place to start: + +1. **Opening an issue.** Before opening an issue, please check that there is not an issue already open. If there is, + feel free to comment more details, explanations, or examples within the open issue rather than duplicating it. + Suggesting changes to the open development process are within the bounds of opening issues. We are always open to + feedback and receptive to suggestions! +2. **Resolving an issue.** You can resolve an issue either by showing that it is not an issue or by fixing the issue + with code changes, additional tests, etc. Any pull request fixing an issue should reference that issue. +3. **Reviewing open PRs.** You can provide comments, standards guidance, naming suggestions, gas optimizations, or ideas + for alternative designs on any open pull request. + +## Opening an Issue + +When opening an [issue](https://github.com/parallel-protocol/parallel-core/issues), please title it with a concise +problem statement and check that a similar request is not already open or in progress. Not all issues may be deemed +worth resolving, so please follow through with responding to any questions or comments that others may have regarding +the issue. + +## Opening a Pull Request + +All pull requests should be opened against the `main` branch. In the pull request, please reference the issue you are +fixing. + +Pull requests can be reviewed by community members, but to be merged they will need approval from the repository +maintainers. Please understand it will take time to receive a response, although the maintainers will aim to respond and +comment as soon as possible. + +**For larger, more substantial changes to the code, it is best to open an issue and start a discussion with the +maintainers to align on the change before spending time on the development.** + +Finally, before opening a pull request please do the following: + +- Run the Foundry tests with `bun run test` +- Document any new functions, structs, or interfaces following the natspec standard. +- Add tests! For smaller contributions, they should be tested with unit tests, and fuzz tests where possible. For bigger + contributions, they should be tested with invariant tests where possible. + +## Standards + +All contributions must follow the below standards. Maintainers will close out PRs that do not adhere to these standards. + +1. All contracts should be formatted with the prettier used in the default vscode config. +2. These contracts follow the [solidity style guide](https://docs.soliditylang.org/en/v0.8.19/style-guide.html) with one + minor exception of using the `\_prependUnderscore` style naming for internal contract functions, internal top-level + parameters, and function parameters with naming collisions. +3. All external facing contracts should inherit from interfaces, which specify and document its functions with natspec. +4. Picking up stale issues by other authors is fine! Please just communicate with them ahead of time and it is best + practice to include co-authors in any commits. +5. Squash commits where possible to make reviews clean and efficient. PRs that are merged to main will be squashed into + 1 commit. + +## Code of Conduct + +Above all else, please be respectful of the people behind the code. Any kind of aggressive or disrespectful comments, +issues, and language will be removed. + +Issues and PRs that are obviously spam and unhelpful to the development process or unrelated to the core code will also +be closed. diff --git a/README.md b/README.md index 69dac78..6cee0d7 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,9 @@ The Parallel Core own the following contracts: [Openzeppelin AccessManager](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/manager/AccessManager.sol) contract. Handle all access for the protocol. -## 4. Getting Started +## Deployment Addresses + +## Development ### Foundry @@ -49,6 +51,15 @@ bun run test You will find other useful commands in the [package.json](./package.json) file. +## Contributing + +If you're interested in contributing, please see our [contributions guidelines](./CONTRIBUTING.md). + +## Questions & Feedback + +For any question or feedback you can use [discord](https://discord.com/invite/mimodao). Don't hesitate to reach out on +[Twitter](https://twitter.com/mimo_labs)🐦 as well. + ## Licences All contracts is under the `MIT` License, see [`LICENSE`](./LICENSE). From 09055543bcdaf8dfcaa3fd561ad17cc90d74640f Mon Sep 17 00:00:00 2001 From: FabienC Date: Wed, 19 Mar 2025 13:50:53 +0200 Subject: [PATCH 03/11] refactor: clean comments and files --- bun.lockb | Bin 159912 -> 160816 bytes contracts/access/AccessManager.sol | 2 +- contracts/libraries/RolesLib.sol | 2 +- deploy/{scripts => }/00_AccessManager.ts | 1 + deploy/utils/index.ts | 27 -------------- deploy/utils/types.ts | 43 ----------------------- package.json | 1 + 7 files changed, 4 insertions(+), 72 deletions(-) rename deploy/{scripts => }/00_AccessManager.ts (99%) delete mode 100644 deploy/utils/index.ts delete mode 100644 deploy/utils/types.ts diff --git a/bun.lockb b/bun.lockb index 57d124e9bc1182ed4055552fcbe1081fc2afdf53..072b91e18624862fa3cdb8fa021e8b340d0c1b9b 100755 GIT binary patch delta 11603 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

<=}q8g)i#&Rb$O*bk?GrOgF5)#Fpa=AI62>b9^D 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 diff --git a/contracts/access/AccessManager.sol b/contracts/access/AccessManager.sol index 97500f5..487db18 100644 --- a/contracts/access/AccessManager.sol +++ b/contracts/access/AccessManager.sol @@ -6,7 +6,7 @@ import { AccessManager as OZAccessManager } from "@openzeppelin/contracts/access import { Roles } from "contracts/libraries/RolesLib.sol"; /// @title AccessManager -/// @author Parallel Labs +/// @author Cooper Labs /// @custom:contact security@cooperlabs.xyz /// @notice Contract inheriting from OpenZeppelin's AccessManager contract. contract AccessManager is OZAccessManager { diff --git a/contracts/libraries/RolesLib.sol b/contracts/libraries/RolesLib.sol index c65032b..3d8360e 100644 --- a/contracts/libraries/RolesLib.sol +++ b/contracts/libraries/RolesLib.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.28; /// @title RolesLib -/// @author Parallel Labs +/// @author Cooper Labs /// @custom:contact security@cooperlabs.xyz /// @notice Library exposing base roles for Parallel Access Manager contracts. library Roles { diff --git a/deploy/scripts/00_AccessManager.ts b/deploy/00_AccessManager.ts similarity index 99% rename from deploy/scripts/00_AccessManager.ts rename to deploy/00_AccessManager.ts index 75404d4..76bf017 100644 --- a/deploy/scripts/00_AccessManager.ts +++ b/deploy/00_AccessManager.ts @@ -1,4 +1,5 @@ import assert from "assert"; + import { type DeployFunction } from "hardhat-deploy/types"; const contractName = "AccessManager"; diff --git a/deploy/utils/index.ts b/deploy/utils/index.ts deleted file mode 100644 index 2756821..0000000 --- a/deploy/utils/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ethers } from "ethers"; -import { Address, ConfigData } from "./types"; - -// return token address defined in config.tokens -export const getTokenAddressFromConfig = (token: string, config: ConfigData) => { - if (!Object.keys(config.tokens).includes(token.toLowerCase())) throw new Error(`Token ${token} not found in config`); - const tokenAddress = config.tokens[token.toLowerCase() as keyof typeof config.tokens]; - if (!isAddressValid(tokenAddress)) throw new Error(`Invalid ${token} address: ${tokenAddress}`); - return tokenAddress; -}; - -export const getWalletAddressFromConfig = (wallet: string, config: ConfigData) => { - if (!Object.keys(config.wallets).includes(wallet.toLowerCase())) - throw new Error(`Wallet ${wallet} not found in config`); - const walletAddress = config.wallets[wallet.toLowerCase() as keyof typeof config.wallets]; - if (!isAddressValid(walletAddress)) throw new Error(`Invalid ${wallet} address: ${walletAddress}`); - return walletAddress; -}; - -export const checkAddressValid = (address: Address, label: string) => { - if (!isAddressValid(address)) throw new Error(`Invalid ${label} address: ${address}`); - return address; -}; - -export const isAddressValid = (address: string) => { - return ethers.utils.isAddress(address) && ethers.constants.AddressZero !== address; -}; diff --git a/deploy/utils/types.ts b/deploy/utils/types.ts deleted file mode 100644 index 8972662..0000000 --- a/deploy/utils/types.ts +++ /dev/null @@ -1,43 +0,0 @@ -import type { BigNumberish } from "ethers"; - -export type Address = `0x${string}`; - -export type ConfigData = { - isMainChainFeeDistributor: boolean; - accessManager: Address; - wallets: { - dao: Address; - }; - tokens: { - prl: Address; - paUSD: Address; - par: Address; - weth: Address; - }; - rewardMerkleDistributor: { - token: string; - expiredRewardsRecipient: string; - }; - feeDistributor: { - feeToken: string; - mainChain: string; - destinationReceiver: Address; - bridgeableToken: Address; - }; - sprl1: { - underlying: Address; - feeReceiver: string; - startPenaltyPercentage: BigNumberish; - timeLockDuration: number; - }; - sprl2: { - feeReceiver: string; - startPenaltyPercentage: BigNumberish; - timeLockDuration: number; - balancerV3Vault: Address; - auraVault: Address; - auraBoosterLite: Address; - auraBPT: Address; - balancerBPT: Address; - }; -}; diff --git a/package.json b/package.json index 4c1783c..e9cbfa8 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ }, "devDependencies": { "forge-std": "github:foundry-rs/forge-std#v1.9.5", + "hardhat": "^2.22.19", "hardhat-contract-sizer": "^2.10.0", "hardhat-deploy": "^1.0.1", "prettier": "^3.0.0", From 60c586a261cec972db5b61cc61ec5bd0f12ced82 Mon Sep 17 00:00:00 2001 From: FabienC Date: Wed, 19 Mar 2025 13:56:04 +0200 Subject: [PATCH 04/11] docs: add security part --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 6cee0d7..5397fc0 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,17 @@ The Parallel Core own the following contracts: [Openzeppelin AccessManager](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/manager/AccessManager.sol) contract. Handle all access for the protocol. +## Documentation Links + ## Deployment Addresses +## Security + +### Assumptions + +- Roles and wallets assigned to roles will must be tracked +- Admin of AccessManager must be a multisig wallet + ## Development ### Foundry From 077f74b2d1655a0b8e3f4f46285a2c9ad27d5709 Mon Sep 17 00:00:00 2001 From: FabienC Date: Wed, 19 Mar 2025 13:56:39 +0200 Subject: [PATCH 05/11] docs: add audit part --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5397fc0..fcf86cd 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ The Parallel Core own the following contracts: - Roles and wallets assigned to roles will must be tracked - Admin of AccessManager must be a multisig wallet +### Audits + ## Development ### Foundry @@ -37,15 +39,13 @@ bun i ### Fill the `.env` file with your data -The Foundry script relies solely on the PRIVATE_KEY. The MNEMONIC is used on the Hardhat side and will override the -PRIVATE_KEY if it is defined. - ```bash -# You don't need to set both of these values, just pick the one that you prefer and set that one PRIVATE_KEY="PRIVATE KEY" ALCHEMY_API_KEY="ALCHEMY_API_KEY" ``` +check .env.example for others env variable + ### Compile contracts ```bash From 4cd3ceabb40418faba8042cfecef72d730b340e9 Mon Sep 17 00:00:00 2001 From: FabienC Date: Wed, 19 Mar 2025 17:52:49 +0200 Subject: [PATCH 06/11] docs: update env part --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fcf86cd..72b46f7 100644 --- a/README.md +++ b/README.md @@ -37,14 +37,16 @@ The Parallel Core own the following contracts: bun i ``` -### Fill the `.env` file with your data +### Setup `.env` file ```bash PRIVATE_KEY="PRIVATE KEY" ALCHEMY_API_KEY="ALCHEMY_API_KEY" ``` -check .env.example for others env variable +For additional keys, you can check the [`.env.example`](/.env.example) file. + +**Warning: always keep your confidential information safe** ### Compile contracts From c9778fa21af5243ecf9735acd0180a81abefa805 Mon Sep 17 00:00:00 2001 From: FabienC Date: Wed, 19 Mar 2025 18:18:03 +0200 Subject: [PATCH 07/11] fix: slither and missing lib --- .gitignore | 58 ++++++++++++++++++++++++++++++++------------ bun.lockb | Bin 160816 -> 168313 bytes package.json | 9 ++++--- slither.config.json | 4 +++ solhint.config.js | 13 ++++++++++ tsconfig.json | 13 ++++++++++ 6 files changed, 78 insertions(+), 19 deletions(-) create mode 100644 slither.config.json create mode 100644 solhint.config.js create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index e108b40..950dc79 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,46 @@ -# directories -cache -coverage +## Defaults +__pycache__ +.idea +.DS_Store +.deps +.docs +.env node_modules -out +venv +myforge -# files -*.env -*.log -.DS_Store -.pnp.* +# Build output +/cache-hh +build +export +**/artifacts +.openzeppelin +typechain +slither-audit.txt +slither +cache + +# Test output +coverage +coverage.json lcov.info -package-lock.json -pnpm-lock.yaml -yarn.lock +reports/ + +# Running output +gas-report.txt +gasReporterOutput.json +addresses.json +blockchain_db +yarn-error.log +broadcast + +# deployments +deployments/localhost +deployments/mainnetForkRemote + +# bin +bin -# broadcasts -!broadcast -broadcast/* -broadcast/*/31337/ +# foundry +/out +/cache-forge diff --git a/bun.lockb b/bun.lockb index 072b91e18624862fa3cdb8fa021e8b340d0c1b9b..b99667b62f9de467bc549a69040fb07b2f9af343 100755 GIT binary patch delta 40429 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

&GAoISm!dskYQDo4GP}0ZK->hrW<#;8jRc4 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

B+!+U-m~}fQ$;##TyD52@EP8Ii+(z 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 NUf0s?ooe0oe*i7KA*%oY diff --git a/package.json b/package.json index e9cbfa8..888909b 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,13 @@ "version": "1.0.0", "private": true, "scripts": { - "compile": "forge build", + "compile": "forge build && hardhat compile", "clean": "rm -rf cache out", - "build": "forge build", "lint": "bun run lint:sol && bun run prettier:check", "lint:sol": "forge fmt --check && bun solhint \"{script,src,tests}/**/*.sol\"", "prettier:check": "prettier --check \"**/*.{json,md,yml}\" --ignore-path \".prettierignore\"", "prettier:write": "prettier --write \"**/*.{json,md,yml}\" --ignore-path \".prettierignore\"", + "slither": "slither . --triage-mode", "test": "forge test", "test:coverage": "forge coverage", "test:coverage:report": "forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir coverage" @@ -19,11 +19,14 @@ "@openzeppelin/contracts": "^5.0.1" }, "devDependencies": { + "dotenv": "^16.4.7", "forge-std": "github:foundry-rs/forge-std#v1.9.5", "hardhat": "^2.22.19", "hardhat-contract-sizer": "^2.10.0", "hardhat-deploy": "^1.0.1", "prettier": "^3.0.0", - "solhint": "^3.6.2" + "solhint": "^3.6.2", + "ts-node": "^10.9.2", + "typescript": "^5.8.2" } } diff --git a/slither.config.json b/slither.config.json new file mode 100644 index 0000000..80b8cb6 --- /dev/null +++ b/slither.config.json @@ -0,0 +1,4 @@ +{ + "detectors_to_exclude": "naming-convention,solc-version", + "filter_paths": "(tests|scripts|node_modules)" +} diff --git a/solhint.config.js b/solhint.config.js new file mode 100644 index 0000000..3c39718 --- /dev/null +++ b/solhint.config.js @@ -0,0 +1,13 @@ +module.exports = { + rules: { + 'code-complexity': ['error', 9], + 'compiler-version': ['error', '>=0.8.19'], + 'func-visibility': ['error', { ignoreConstructors: true }], + 'max-line-length': ['error', 136], + 'named-parameters-mapping': 'warn', + 'not-rely-on-time': 'off', + 'one-contract-per-file': 'off', + 'avoid-low-level-calls': 'off', + 'no-global-import': 'off', + }, +}; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..946a3ce --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "exclude": ["node_modules"], + "include": ["./hardhat.config.ts", "./scripts", "./deploy"], + "compilerOptions": { + "target": "es2020", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true + } +} From 1d52b7363b41e1ad735d5259999a8a349db4b6b1 Mon Sep 17 00:00:00 2001 From: FabienC Date: Thu, 20 Mar 2025 09:59:39 +0200 Subject: [PATCH 08/11] docs: harmonize parallel docs --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 72b46f7..e0a2920 100644 --- a/README.md +++ b/README.md @@ -34,14 +34,17 @@ The Parallel Core own the following contracts: ### Install js dependencies ```bash -bun i +bun install ``` ### Setup `.env` file +In order to interact with non local networks, you must create an `.env` that has: + ```bash PRIVATE_KEY="PRIVATE KEY" ALCHEMY_API_KEY="ALCHEMY_API_KEY" +MAINNET_ETHERSCAN_API_KEY="MAINNET_ETHERSCAN_API_KEY" ``` For additional keys, you can check the [`.env.example`](/.env.example) file. @@ -60,6 +63,12 @@ bun run compile bun run test ``` +### [Slither](https://github.com/crytic/slither) + +```bash +bun run slither +``` + You will find other useful commands in the [package.json](./package.json) file. ## Contributing @@ -69,7 +78,7 @@ If you're interested in contributing, please see our [contributions guidelines]( ## Questions & Feedback For any question or feedback you can use [discord](https://discord.com/invite/mimodao). Don't hesitate to reach out on -[Twitter](https://twitter.com/mimo_labs)🐦 as well. +[Twitter](https://twitter.com/mimo_labs) as well. ## Licences From d91238334e3a015fb990db24fd66f9dd7dc59ffa Mon Sep 17 00:00:00 2001 From: FabienC Date: Thu, 20 Mar 2025 10:00:24 +0200 Subject: [PATCH 09/11] docs: update license --- LICENSE.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 0424fa0..9a67277 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,4 @@ -MIT License - -Copyright (c) 2024 Paul Razvan Berg +Copyright 2024 CooperLabs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the From 0d3dcffb62988f806c3c0b1f75efe19e45dce822 Mon Sep 17 00:00:00 2001 From: FabienC Date: Thu, 20 Mar 2025 12:08:15 +0200 Subject: [PATCH 10/11] docs: add CoC --- CODE_OF_CONDUCT.md | 101 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..c681802 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,101 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for +everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity +and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, +or sexual identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take +appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, +issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for +moderation decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing +the community in public spaces. Examples of representing our community include using an official e-mail address, posting +via an official social media account, or acting as an appointed representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible +for enforcement at contact@cooperlabs.xyz. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem +in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the +community. + +**Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation +and an explanation of why the behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of actions. + +**Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including +unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding +interactions in community spaces as well as external channels like social media. Violating these terms may lead to a +temporary or permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified +period of time. No public or private interaction with the people involved, including unsolicited interaction with those +enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate +behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. +Translations are available at https://www.contributor-covenant.org/translations. From 44bb5a697a36a0bd060accddb92e4612f05d4ca1 Mon Sep 17 00:00:00 2001 From: FabienC Date: Thu, 20 Mar 2025 12:08:39 +0200 Subject: [PATCH 11/11] docs: update link --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7d97e4..760dfd7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,10 +21,10 @@ There are many ways to contribute, but here are a few if you want a place to sta ## Opening an Issue -When opening an [issue](https://github.com/parallel-protocol/parallel-core/issues), please title it with a concise -problem statement and check that a similar request is not already open or in progress. Not all issues may be deemed -worth resolving, so please follow through with responding to any questions or comments that others may have regarding -the issue. +When opening an [issue](https://github.com/parallel-protocol/parallel-parallelizer/issues), please title it with a +concise problem statement and check that a similar request is not already open or in progress. Not all issues may be +deemed worth resolving, so please follow through with responding to any questions or comments that others may have +regarding the issue. ## Opening a Pull Request