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 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/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. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..760dfd7 --- /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-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 + +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/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 diff --git a/README.md b/README.md index 69dac78..e0a2920 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,20 @@ 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 +## Documentation Links + +## Deployment Addresses + +## Security + +### Assumptions + +- Roles and wallets assigned to roles will must be tracked +- Admin of AccessManager must be a multisig wallet + +### Audits + +## Development ### Foundry @@ -21,20 +34,23 @@ The Parallel Core own the following contracts: ### Install js dependencies ```bash -bun i +bun install ``` -### Fill the `.env` file with your data +### Setup `.env` file -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. +In order to interact with non local networks, you must create an `.env` that has: ```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" +MAINNET_ETHERSCAN_API_KEY="MAINNET_ETHERSCAN_API_KEY" ``` +For additional keys, you can check the [`.env.example`](/.env.example) file. + +**Warning: always keep your confidential information safe** + ### Compile contracts ```bash @@ -47,8 +63,23 @@ 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 + +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). diff --git a/bun.lockb b/bun.lockb index 57d124e..b99667b 100755 Binary files a/bun.lockb and b/bun.lockb differ 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..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,10 +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 + } +}