{"id":30896924,"url":"https://github.com/circlefin/evm-gateway-contracts","last_synced_at":"2025-09-08T23:47:58.829Z","repository":{"id":295864322,"uuid":"979645318","full_name":"circlefin/evm-gateway-contracts","owner":"circlefin","description":"Official repository for all EVM-compatible smart contracts used by Circle Gateway","archived":false,"fork":false,"pushed_at":"2025-07-17T22:09:19.000Z","size":3605,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-07-18T01:30:17.422Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/circlefin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-07T20:59:41.000Z","updated_at":"2025-07-17T22:09:21.000Z","dependencies_parsed_at":"2025-07-18T01:52:55.333Z","dependency_job_id":null,"html_url":"https://github.com/circlefin/evm-gateway-contracts","commit_stats":null,"previous_names":["circlefin/evm-gateway-contracts"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/circlefin/evm-gateway-contracts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fevm-gateway-contracts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fevm-gateway-contracts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fevm-gateway-contracts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fevm-gateway-contracts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/circlefin","download_url":"https://codeload.github.com/circlefin/evm-gateway-contracts/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fevm-gateway-contracts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274231139,"owners_count":25245675,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-08T02:00:09.813Z","response_time":121,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-08T23:47:51.134Z","updated_at":"2025-09-08T23:47:58.812Z","avatar_url":"https://github.com/circlefin.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Circle Gateway Contracts\n\nThese are the contracts that support the Circle Gateway product. See the contract docs or Circle's website for more information about the product and how to use it.\n\n## Install dependencies\n\n- Run `git submodule update --init --recursive` to update/download all libraries.\n- Ensure Yarn is installed and then run `yarn install` to install additional JS dependencies.\n\n## Install Foundry CLI\n\n- Run `curl -L https://foundry.paradigm.xyz | bash`\n- Follow the instructions of that command to source env file\n- run `foundryup --install v1.0.0`\n\n## Deployment\n\n### How it works\n\nThe deployment steps are:\n\n1. Deploy the `UpgradablePlaceholder` implementation\n2. Deploy the actual implementation (e.g. `GatewayMinter`)\n3. Deploy the ERC1967Proxy and setup the proxy:\n   1. Deploy the ERC1967 Proxy, set the implementation to `UpgradablePlaceholder` and initialize the owner to Create2Factory address.\n   2. In the same transcation, upgrade the implementation to actual implementation and initialize the implementation properly.\n\nThe reason of setting owner of `UpgradablePlaceholder` to Create2Factory address is that since the owner is part of the address computation, we want to use Create2Factory to avoid managing an extra EOA key.\n\nSince the owner of `UpgradablePlaceholder` is Create2Factory and only the owner can perform `upgradeToAndCall`, we decided to use `Create2Factory.deployAndMultiCall` to upgrade to actual implementation in the proxy deployment call.\n\n### Prerequisites\n\nBefore deploying the contracts, ensure you have:\n\n1. Create a `.env` file from `.env.example` and set up environment variables in `.env` file.\n\n2. Run `source .env` to load the environment variables in your shell.\n\n3. Verified you have sufficient funds in the deployer account for the target network\n\n### Deploying Contracts\n\n#### Step 1: Start a local blockchain\n\n_Only needed for local deployment_\n\nStart a local RPC node at http://127.0.0.1:8485 by running `anvil`.\n\n#### Step 2: Deploy Create2Factory Contract\n\n_Only needed for local deployment_\n\n##### Local Deployment\n\nRun the following command to deploy a test instance of the Create2Factory contract:\n\n```bash\nforge create Create2Factory -r http://127.0.0.1:8545 --broadcast --private-key $DEPLOYER_PRIVATE_KEY --constructor-args $DEPLOYER_ADDRESS\n```\n\n- `DEPLOYER_PRIVATE_KEY`: Any key from anvil pre-funded addresses.\n- `DEPLOYER_ADDRESS`: This address should match the $DEPLOYER_ADDRESS in `.env`\n\nAdd the deployed Create2Factory contract address to your `.env` file under the variable `LOCAL_CREATE2_FACTORY_ADDRESS`.\n\n##### Local deployment\n\nFollow the instructions in evm-cctp-contracts-private README to deploy Create2Factory. Update `LOCAL_DEPLOYER_ADDRESS` and `LOCAL_CREATE2_FACTORY_ADDRESS` in `.env`.\n\n#### Step3: Generate Deployment Transactions for `GatewayWallet` and `GatewayMinter`.\n\nRun the following command to generate deployment transactions for `GatewayWallet` and `GatewayMinter`:\n\n```bash\nENV=$ENV forge script script/001_DeployGatewayWallet.sol --rpc-url $RPC_URL -vvvv --slow --force\nENV=$ENV forge script script/001_DeployGatewayMinter.sol --rpc-url $RPC_URL -vvvv --slow --force\n```\n\n- `ENV`: Use `LOCAL` for local deployment. Or choose from `TESTNET_STAGING`, `TESTNET_PROD`, and `MAINNET_PROD`.\n- `RPC_URL`: The rpc url for the targeted blockchain. use `http://127.0.0.1:8485` for local deployment.\n\nThe generated transaction data will be available in the `broadcast/` directory and can be used for signing.\n\n### Deployed contract validation\n\nFill in the `Deployed Contract Validation` section in `.env` and run:\n\n```bash\nforge script script/003_DeployedContractValidation.s.sol --rpc-url $RPC_URL -vvvv --slow --force\n```\n\nThis command validates deployed contract bytecode matches expected bytecode and contract state matches expected values.\n\n### How to Update Deployment Scripts\n\n#### Update Compiled Contract Artifacts\n\nRun the following command to generate new artifacts for deployment:\n\n```bash\nyarn artifacts\n```\n\n#### Find New Salts\n\nFind salts that creates gas-efficient proxy addresses via:\n\n```bash\ncast create2 --starts-with $ADDRESS_PREFIX --deployer $DEPLOYER\u003e --init-code-hash $INIT_CODE_HASH\n```\n\n- `ADDRESS_PREFIX` is the prefix of the address we want to find. Usually set to `00000000` for a gas-efficient address.\n- `DEPLOYER` is the address of Create2Factory.\n- `INIT_CODE_HASH` is keccak256 hash of initcode + abi-encoded constuctor argument.\n\nWe have chosen the following prefixes for our top-level contracts:\n\n| Environment | Network Type | Wallet Prefix | Minter Prefix | Notes |\n|:------------------------:|:------------------------:|:------------------------:|:------------------------:|:------------------------:|\n| Production | Mainnet | 0x7777777 | 0x2222222 |  |\n| Production | Testnet | 0x0077777 | 0x0022222 | Add zero byte to mainnet addresses |\n| Staging | Testnet | 0x5577777 | 0x5522222 | 5 = \"S\" for Staging |\n\nTo find and verify salts for the Wallet and Minter contracts, correctly set the `ENV` and `RPC_URL` environment variables (and possible `LOCAL_CREATE2_FACTORY_ADDRESS` depending on your environment). Use any values for all of the other variables, as they do not matter here.\n\nSimulate the deployments by running the below commands and note down the values initCodeHash from the logs of each command\n1. `ENV=$ENV forge script script/001_DeployGatewayWallet.sol --rpc-url $RPC_URL -vv`\n2. `ENV=$ENV forge script script/002_DeployGatewayMinter.sol --rpc-url $RPC_URL -vv`\n\nThen, run the following command:\n\n```shell\n# Use the same value specified in the 000_Constants.sol or `LOCAL_CREATE2_FACTORY_ADDRESS` (depending on your environment)  \nexport SALT_MINE_CREATE2_FACTORY_ADDRESS=\n\n# Use values of previous step's logs\nexport WALLET_PROXY_INIT_CODE_HASH=\nexport MINTER_PROXY_INIT_CODE_HASH=\n\n# Make sure ENV has been set before calling this command (see .env file)\nyarn mine-salts\n```\n\nUpdate the salts in `000_Constants.sol` and re-simulate the deployments to verify that the proxy addresses have been updated to the expected prefixes.\n\n## Test\n\n### Unit Tests and Fork Tests (Foundry)\n\nTo run tests using Foundry, run `yarn test`. This will run all tests using the default Anvil localnet.\n\nTo run tests against each supported network (by forking from each network's RPC endpoint), run `yarn test:all`. If failures related to remote state from an old block are encountered, either point to archive nodes or run `./scripts/update_block_numbers.sh` to pin the latest block for each network and try again.\n\nTo run tests and output a gas report for the top-level contracts, run `yarn test:gas`.\n\n### Mock FiatToken port\n\nTo simplify local development and testing we have a local port of the FiatToken contracts from the https://github.com/circlefin/stablecoin-evm repo. The port is based on commit [0642db6](https://github.com/circlefin/stablecoin-evm/commit/0642db65d656a51d4df21b8d03dd38124ad0e7b3). When there are essential changes to the FiatToken contracts (e.g., new version release), we'll need to:\n\n1. Go through the diff between the above commit and the latest version, applying the latest changes into `test/mock_fiattoken`\n2. Update dependency imports and relative imports\n3. Bump solidity version and fix resulting compiler errors\n4. Update `test/util/DeployMockFiatToken.sol` if necessary\n\n### Linting and Formatting\n\nRun `yarn lint` to lint all `.sol` files in the `src` and `test` directories, and `yarn lint:fix` to automatically fix any fixable linting errors.\n\nRun `yarn format` to check the formatting of all `.sol` files in the `src` and `test` directories, and `yarn format:fix` to automatically format them.\n\n### Coverage\n\nRun `yarn coverage` to generate a coverage report for the tests. This depends on the `lcov` and `genhtml` commands, which may be installed on macOS with `brew install lcov`. The coverage report will be generated in the `coverage` directory.\n\n## Development\n\n### Contract Sizes\n\nTo check the bytecode size of all top-level contracts against the EIP-170 contract size limit, run `yarn sizes`.\n\n### Important Considerations: Memory Initialization with TypedMemView\n\nThis project relies heavily on the `TypedMemView` library (`lib/memview-sol/`) for efficient memory manipulation.\n\n**Warning:** As documented in the [TypedMemView](https://github.com/summa-tx/memview-sol/tree/main) library itself, it utilizes unallocated memory operations and **does not guarantee cleanup of unallocated memory regions** after its internal functions execute.\n\n**Implication:** This means that memory subsequently allocated by contracts in _this_ project (e.g., declaring new `memory` variables like arrays or structs after `TypedMemView` operations have occurred within the same transaction execution path) **might not be zero-initialized**. It could contain residual data from previous operations.\n\n**Required Precaution:** Developers working on this codebase **must not** assume that newly allocated memory variables or structures are automatically zero-initialized. If the logic relies on a memory variable starting at zero (or `false`, `address(0)`, etc.), it **must** be explicitly initialized after allocation.\n\n## Continuous Integration using Github Actions\n\nWe use Github actions to run the linter and all the tests. The workflow configuration can be found in [.github/workflows/pipeline.yml](.github/workflows/pipeline.yml). While not a complete replacement, all CI steps may be run locally with `yarn ci`.\n\n## Manual Triggering of the Olympix CI Workflow\n\nYou can manually trigger the Olympix.ai Code Scanning workflow using the `workflow_dispatch` feature of GitHub Actions.\n\n1. Click on the `Actions` tab.\n2. In the left sidebar, select `Olympix Scan`.\n3. Select the branch \u0026 click on the `Run workflow` button.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcirclefin%2Fevm-gateway-contracts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcirclefin%2Fevm-gateway-contracts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcirclefin%2Fevm-gateway-contracts/lists"}