{"id":21850474,"url":"https://github.com/circlefin/buidl-wallet-contracts","last_synced_at":"2025-04-14T15:02:08.067Z","repository":{"id":257025783,"uuid":"857084528","full_name":"circlefin/buidl-wallet-contracts","owner":"circlefin","description":"Official repository for all buidl wallet contracts","archived":false,"fork":false,"pushed_at":"2025-03-20T17:03:21.000Z","size":2985,"stargazers_count":10,"open_issues_count":3,"forks_count":19,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-28T03:51:09.615Z","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":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/circlefin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-09-13T19:13:50.000Z","updated_at":"2025-03-20T17:02:41.000Z","dependencies_parsed_at":"2024-09-14T12:07:26.640Z","dependency_job_id":"03a3e1e3-ebaa-442a-b61d-70ebd3f1cce3","html_url":"https://github.com/circlefin/buidl-wallet-contracts","commit_stats":null,"previous_names":["circlefin/buidl-wallet-contracts"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fbuidl-wallet-contracts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fbuidl-wallet-contracts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fbuidl-wallet-contracts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/circlefin%2Fbuidl-wallet-contracts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/circlefin","download_url":"https://codeload.github.com/circlefin/buidl-wallet-contracts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248903703,"owners_count":21180828,"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","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":"2024-11-28T00:17:43.714Z","updated_at":"2025-04-14T15:02:08.041Z","avatar_url":"https://github.com/circlefin.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# buidl-wallet-contracts\nOfficial repository for all smart wallet contracts used by Circle web3 API/SDK. \n\nThis repository includes support for both the Hardhat and Foundry frameworks. Going forward, all new code / tests / scripts should be built on Foundry. Hardhat is currently only included for legacy contracts in the following folders:\n- `src/account/v1`\n- `src/paymaster/v1/permissioned`\n\n## Setup\n1. Run `git submodule update --init --recursive` to update/download all libraries.\n2. Run `yarn install` to install any additional dependencies.\n3. Run `curl -L https://foundry.paradigm.xyz | bash` and follow the outputted instructions to source env file. \n4. Run `foundryup`\n5. Create a `.env` file and provide the required API keys, wallets (can be generated for deployment), and configuration values. You can look at the `.env.example` for reference.\n\n## Development\n\n### Lint\nRun `yarn lint` to lint all `.sol` files in the `src` and `test` directories. Run `yarn format:check` and `yarn format:write` to check for, and fix formatting issues, respectively.\n\n### Test\nTo run tests using Foundry, follow the steps below:\n1. Run `yarn build`\n2. Run `yarn test`\n\n### Test Coverage\nTo generate a viewable test coverage report, run:\n- `brew install lcov` if not yet installed\n- `forge coverage --ir-minimum --report lcov \u0026\u0026 genhtml lcov.info -o report --branch-coverage \u0026\u0026 open report/index.html`\n(Note: some contracts like WeightedMultisigPlugin require using --ir-minimum because of stack depth. To build coverage\nfaster locally, comment out this and dependent contracts and omit --ir-minimum flag.)\n\n\n### Continuous Integration\nWe use Github actions to run linter and all the tests. The workflow configuration can be found in [.github/workflows/ci.yml](.github/workflows/ci.yml)\n\n\n### Release\nWe are using [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/) structure to automatically generate releases.\n\n## Export Interface\nTo export contract bytecode \u0026 ABI for programmable wallet:\n1. Execute `forge build src/msca/6900/v0.7 --force --extra-output-files abi evm`. Replace v0.7 with v0.8 if you want v0.8.\n2. Execute `make abigen`\n3. Interface files will appear under `abigen` folder\n4. After changes are merged, release new repository tag\n5. update `buidl-wallet-contracts` go mod version of programmable-wallet, and import bytecode from `abigen` folder\n\nFor running integration tests in Anvil node, run `make anvil-tests`. This runs the python tests in [test/anvil](test/anvil/)\n\n## Gas Report\n### Function report\n* Run `yarn build`\n* Run `yarn gasreport`\n\n### E2E gas benchmarking\n* `anvil`\n* update `.env` (pointing to local) and `source .env`\n* deploy (only choose the account type you're interested in benchmarking)\n  * `forge script script/\u003cSCRIPT_NAME\u003e --rpc-url $RPC_URL --broadcast --verify -vvvv --slow --watch`\n\n    Example: `forge script script/001_DeployPluginManager.s.sol --rpc-url $RPC_URL --broadcast --verify -vvvv --slow --watch`\n\n* `cast code $address`\n\n## On-chain Deployment \u0026 Verification\n\n### Start a Local Network (optional, for testing)\n\n`npx hardhat node` (if using hardhat stack)\n\n`make anvil` (if using foundry stack). To get a list of pre-funded addresses, you can look at the beginning of the logs in the `anvil` Docker container, or reference \u003chttps://github.com/foundry-rs/foundry/blob/0d8302880b79fa9c3c4aa52ab446583dece19a34/crates/anvil/README.md?plain=1#L48\u003e.\n\n### (NEW) Deploy \u0026 Verify\nscripts and artifacts under `./script/bytecode-deploy` are using bytecode deployment and standard json input verification.\n\n#### artifact generation\nThese steps are not needed for chain expansion. They're documented to show how to properly add artifacts if new deployment scripts are added.\n\nFor each smart contract needs to be deployed, repeat the following steps:\n1. Force build the smart contract.\n2. Copy the necessary build outputs from `./out` to `./script/bytecode-deploy/build-output`. Sometimes it's more than the contract itself.\n3. Generate the standard json input to `./script/bytecode-deploy/standard-json-input`.\n\nThe full set of commands are:\n```shell\n# PluginManager\nforge build src/msca/6900/v0.7/managers/PluginManager.sol --force\ncp out/PluginManager.sol/PluginManager.json script/bytecode-deploy/build-output/PluginManager.json\nforge verify-contract -c \u003cCHAIN_ID\u003e --optimizer-runs 200 --via-ir \u003cPLUGIN_MANAGER_ADDRESS\u003e src/msca/6900/v0.7/managers/PluginManager.sol:PluginManager --show-standard-json-input \u003e script/bytecode-deploy/standard-json-input/PluginManager.json\n\n# UpgradableMSCAFactory (Build outputs of UpgradableMSCA and ERC1967Proxy are added for SDK)\nforge build src/msca/6900/v0.7/factories/UpgradableMSCAFactory.sol --force\ncp out/UpgradableMSCAFactory.sol/UpgradableMSCAFactory.json script/bytecode-deploy/build-output/UpgradableMSCAFactory.json\ncp out/UpgradableMSCA.sol/UpgradableMSCA.json script/bytecode-deploy/build-output/UpgradableMSCA.json\ncp out/ERC1967Proxy.sol/ERC1967Proxy.json script/bytecode-deploy/build-output/ERC1967Proxy.json\nforge verify-contract -c \u003cCHAIN_ID\u003e --optimizer-runs 200 --via-ir \u003cFACTORY_ADDRESS\u003e --constructor-args $(cast abi-encode \"constructor(address,address,address)\" \u003cMSCA_FACTORY_OWNER_ADDRESS\u003e \u003cENTRY_POINT_V07\u003e \u003cPLUGIN_MANAGER_ADDRESS\u003e) src/msca/6900/v0.7/factories/UpgradableMSCAFactory.sol:UpgradableMSCAFactory --show-standard-json-input \u003e script/bytecode-deploy/standard-json-input/UpgradableMSCAFactory.json\ncast abi-encode \"constructor(address,address,address)\" \u003cMSCA_FACTORY_OWNER_ADDRESS\u003e \u003cENTRY_POINT_V07\u003e \u003cPLUGIN_MANAGER_ADDRESS\u003e | sed -e \"s/^0x//\" \u003e script/bytecode-deploy/standard-json-input/UpgradableMSCAFactory_constructor_args\n\n# UpgradableMSCA (build output of UpgradableMSCAFactory is used for verification, we only need to generate constructor args)\ncast abi-encode \"constructor(address,address)\" \u003cENTRY_POINT_V07\u003e \u003cPLUGIN_MANAGER_ADDRESS\u003e | sed -e \"s/^0x//\" \u003e script/bytecode-deploy/standard-json-input/UpgradableMSCA_constructor_args\n\n# ColdStorageAddressBookPlugin\nforge build src/msca/6900/v0.7/plugns/v1_0_0/addressbook/ColdStorageAddressBookPlugin.sol --force\ncp out/ColdStorageAddressBookPlugin.sol/ColdStorageAddressBookPlugin.json script/bytecode-deploy/build-output/ColdStorageAddressBookPlugin.json\nforge verify-contract -c \u003cCHAIN_ID\u003e --optimizer-runs 200 --via-ir \u003cPLUGIN_ADDRESS\u003e src/msca/6900/v0.7/plugins/v1_0_0/addressbook/ColdStorageAddressBookPlugin.sol:ColdStorageAddressBookPlugin --show-standard-json-input \u003e script/bytecode-deploy/standard-json-input/ColdStorageAddressBookPlugin.json\n\n# WeightedWebauthnMultisigPlugin\nforge build src/msca/6900/v0.7/plugins/v1_0_0/multisig/WeightedWebauthnMultisigPlugin.sol --force\ncp out/WeightedWebauthnMultisigPlugin.sol/WeightedWebauthnMultisigPlugin.json script/bytecode-deploy/build-output/WeightedWebauthnMultisigPlugin.json\nforge verify-contract -c \u003cCHAIN_ID\u003e --optimizer-runs 200 --via-ir \u003cFACTORY_ADDRESS\u003e --constructor-args $(cast abi-encode \"constructor(address)\" \u003cENTRY_POINT_V07\u003e) src/msca/6900/v0.7/plugins/v1_0_0/multisig/WeightedWebauthnMultisigPlugin.sol:WeightedWebauthnMultisigPlugin --show-standard-json-input \u003e script/bytecode-deploy/standard-json-input/WeightedWebauthnMultisigPlugin.json\ncast abi-encode \"constructor(address)\" \u003cENTRY_POINT_V07\u003e | sed -e \"s/^0x//\" \u003e script/bytecode-deploy/standard-json-input/WeightedWebauthnMultisigPlugin_constructor_args\n```\n\n#### Deployment script\nThis step is not needed for chain expansion. We only need to add deployment script if new smart contracts are added.\n1. Writing a new deployment script. There are examples files ending in s.sol in script/bytecode-deploy.\n2. Salt mining with `cast create2` to find a salt that generates the address with 8 leading zeros.\n3. Use the salt in deployment script.\n4. Adjust the chains in `100_Constants.sol` accordingly.\n\n#### Deploy\nDeployment scripts are under script/bytecode-deploy. Deploy command is:\n```shell\nforge script script/bytecode-deploy/\u003cSCRIPT_FILE\u003e  -vvvv --slow --broadcast --force --multi\n```\n\n#### Verification\nUse the standard json output and constructor arg file under script/bytecode-deploy.standard-json-input to verify smart contracts in block explorer.\n\n### Deploy \u0026 Verify\n#### SCA and Paymaster\n  1. Deployment\n      * Run the command `env $(grep -v '^#' .env) yarn hardhat deploy --network \u003cchain\u003e` where `\u003cchain\u003e` is one of {`mumbai`, `goerli`}.\n\n        If you only want to deploy a specific set of smart contracts, you can add the `--tags` flag, for example: `env $(grep -v '^#' .env) yarn hardhat deploy --tags SponsorPaymaster --network goerli`\n  2. Verification\n      * ECDSA wallet factory `env $(grep -v '^#' .env) npx hardhat verify --network mumbai --constructor-args script/ecdsa_account_factory_constructor_args.js ECDSA_ACCOUNT_FACTORY_ADDRESS`\n      * Sponsor paymaster `env $(grep -v '^#' .env) npx hardhat verify --network goerli --constructor-args script/sponsor_paymaster_constructor_args.js STABLECOIN_PAYMASTER_ADDRESS`\n      * Fallback: If the verification commands do not work for contracts deployed through the hardhat deployment scripts, you can still verify manually through etherscan's UI by submitting the standard input json. \n      \n        You can find this file under `deployments/polygon/solcInputs` (you can try different blockchains but I'm unsure of results). Then submit the file that you think is the one for the contract you're trying to verify. It's a bit of guessing, but you can look at the source code to try and figure it out. You may also need to verify the proxies manually through etherscan after having verified the implementation.\n#### MSCA\n  1. Set up `DEPLOYER_PRIVATE_KEY`, `RPC_URL` and `ETHERSCAN_API_KEY` in .env\n  2. Run `source .env`\n  3. Run the desired numbered scripts inside the `script/` folder using the below command format. Make sure any environment variable values from previous steps are updated if needed as you progress through the scripts.\n       * `forge script script/\u003cSCRIPT_NAME\u003e --rpc-url $RPC_URL --broadcast --verify -vvvv`\n       \n          Example: `forge script script/001_DeployPluginManager.s.sol --rpc-url $RPC_URL --broadcast --verify -vvvv`\n\n      Tip: before executing the above command, verify the simulation works as expected by running the above command without the `--broadcast` and `--verify` flags. This way, you can also make sure your address will have enough tokens to cover the transaction fee estimated in the simulation.\n\n      Note: if you are deploying on a local network, don't use the `--verify` flag.\n    \n  4. Include the relevant logs from the `broadcast` folder in your commit.\n\n        Tip: if you did multiple runs, search the appropriate block explorer for the tx hash corresponding to the desired contract's deployment, and then search the logs for the transaction hash.\n\n        Tip: logs are organized by chain ID in the lower levels in the `broadcast` folder. Use \u003chttps://chainlist.org/\u003e to lookup IDs of common chains.\n\n  5. Create or update the corresponding file in the `script/cmd` folder using the creation bytecode of the contract from the logs. See the below \"Chain Expansion\" section for details on how to format the files in the `script/cmd` folder.\n  6. Verify in block explorer like etherscan using standard input json\n       * Create the standard input json: run the below command\n       \n          ```shell\n          forge verify-contract \u003ccontract_address\u003e \u003crelative_path_to_source:classname\u003e --show-standard-json-input \u003e \u003cscript/verify/\u003cfilename\u003e\n\n          # Example\n          forge verify-contract 0x03431fb00fb2e26b5bc502dfef8da30e1c8643b8 src/msca/6900/v0.7/plugins/v1_0_0/utility/DefaultTokenCallbackPlugin.sol:DefaultTokenCallbackPlugin --show-standard-json-input \u003e script/verify/DefaultTokenCallbackPlugin.json\n          ```\n       * Verify and publish in block explorer (etherscan example)\n         * Compiler type: `Solidity (Standard-Json-Input)`\n         * Compiler version: `v0.8.24`\n         * License: Option 5 in https://etherscan.io/contract-license-types\n         * Upload the JSON file\n         * If the contract you are verifying took constructor arguments, input the output of the below command with the `0x` prefix removed into the \"Constructor Arguments ABI-encoded\" section:\n\n            ```shell\n            cast abi-encode \"constructor(\u003carg type 1\u003e, \u003carg type 2\u003e, ...)\" \"arg1Val\" \"arg2Val\"\n\n            # Example\n            cast abi-encode \"constructor(address,address,uint256)\" \"0x0166EA90E565476f13c6a0D25ED2C35599E58785\" \"0x0000000071727De22E5E9d8BAf0edAc6f37da032\" 18\n            ```\n\n            Make sure to save this output under `script/verify/\u003cContractName\u003e/abiEncodedConstructorArgs`.\n            \n            Tip: if your contract's constructor arguments have complicated types, you can get this value instead by `console.log`ing the output of `abi.encode(arg1, arg2, ...)` in Solidity.\n\n          * For account factory contracts, you may also need to manually verify the proxy contract. To do this, you will first need to create an account using the account factory, and follow the above strategy. After verifying one account, all subsequent proxies should be automatically detected.\n\n            Tip: analyze the account creation function on the factory (e.g. `createAccount` for `SingleOwnerMSCAFactory`) to deduce the constructor arguments for the proxy deployment when trying to verify it on a block explorer.\n\n         * Click verify and publish\n\n### Deployment Metadata\n\nThe below contract deployment are based on abi and bytecode to ensure the same address across all EVM-compatible chains. The abi and bytecode for each of the contracts are available at the locations below. These files were generated from first deployments, will all fields except `abi` and `bytecode` removed.\n\n| Contract Name | Location |\n|:------------------------:|:------------------------:|\n| ECDSAAcountFactory | `deploy/metadata/ECDSAAccountFactory.json` |\n| SponsorPaymaster_Implementation | `deploy/metadata/SponsorPaymaster_Implementation.json` |\n| SponsorPaymaster_Proxy | `deploy/metadata/SponsorPaymaster_Proxy.json` |\n\n### Chain Expansion\n\nTo ensure consistent deployment of contracts across chains, we store the `cast send` deployment commands for contracts in the `script/cmd` folder. To deploy these contracts, simply run the command inside the file corresponding to that contract on the command line.\n\nTo build the `cast send` deployment command for a contract:\n1. Run the Solidity deployment script for the contract in the `script/*` folder:\n1. Find the deployment result in broadcast/*\n2. Looking for “transactions” -\u003e ”transaction” → “data” in run-*.json\n3. Copy the \"data\" in step 2 without \"0x\" prefix. \n4. Add `cast send --rpc-url $RPC_URL --private-key $DEPLOYER_PRIVATE_KEY 0x4e59b44847b379578588920cA78FbF26c0B4956C 0x0000000000000000000000000000000000000000000000000000000000000000` in front of the bytecode from previous step (no space)\n\n   Refer to the note after these steps, you may not need the `0x0...` prefix. The `0x4e59b44847b379578588920cA78FbF26c0B4956C` is foundry's default create2 address deployer. See \u003chttps://book.getfoundry.sh/reference/cast/cast-create2\u003e.\n5. Run the command in step5 in Terminal.\n6. Save this command to script/cmd folder with `\u003cscript_name\u003e`\n7. Create the README under `broadcast` folder for the chain id. For example, see `broadcast/011_DeployTokenCallbackPlugin.s.sol/11155111/README.md`\n\nNote: The \"data\" field may be called \"input\". Additionally, if the input/data field already contains the leading `0000000000000000000000000000000000000000000000000000000000000000` prefix, simply copy this value over directly (no need to re-add the zeros prefix).\n\n## Troubleshooting\n#### 1. `make: *** [test] Error 137`\n\nIf you encountered this error after executing `make test`, try increasing memory resource for docker engine.\n\n#### 2. Encounter `ERROR: failed to solve: operating system is not supported` when executing `make build`\nIf you are using macbook with M1 or newer chips, try enabling `Use Rosetta for x86/amd64 emulation on Apple Silicon` under `Features in development` in Docker settings.\n\n#### 3. Docker container `foundry:latest` not found\nAs an alternative to the above, if you are using macbook with M1 or newer chips, try adding the `--platform=linux/amd64` flag to the `build` Make command. If you encounter this error while running `make anvil`, make sure to run `make` before.\n\n#### 4. API key errors when running deploy scripts on a local blockchain\nWhen deploying contract deployment scripts from the `/script` folder on a local chain (started up using `make anvil`), you can remove the `--verify` flag if you are getting errors related to the API key, such as `Missing etherscan key for chain 31337`.\n\n#### 5. failed to read artifact source file for ...\n\nRun `forge clean \u0026\u0026 forge build`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcirclefin%2Fbuidl-wallet-contracts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcirclefin%2Fbuidl-wallet-contracts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcirclefin%2Fbuidl-wallet-contracts/lists"}