{"id":15629709,"url":"https://github.com/paulrberg/prb-proxy","last_synced_at":"2025-04-08T10:28:19.927Z","repository":{"id":37400442,"uuid":"401679578","full_name":"PaulRBerg/prb-proxy","owner":"PaulRBerg","description":"Proxy contract to compose Ethereum transactions","archived":false,"fork":false,"pushed_at":"2024-12-26T16:07:34.000Z","size":8520,"stargazers_count":277,"open_issues_count":7,"forks_count":48,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-04-01T09:33:39.014Z","etag":null,"topics":["blockchain","delegatecall","ethereum","prb-proxy","proxy","smart-contracts","solidity"],"latest_commit_sha":null,"homepage":"https://prbproxy.com","language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PaulRBerg.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":"audits/cantina-2023-07-11.pdf","citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":"https://3cities.xyz/#/pay?c=CAESFAKY9DMuOFdjE4Wzl2YyUFipPiSfIgICATICCAJaFURvbmF0aW9uIHRvIFBhdWwgQmVyZw","github":"PaulRBerg"}},"created_at":"2021-08-31T11:33:52.000Z","updated_at":"2025-03-17T21:30:37.000Z","dependencies_parsed_at":"2023-10-04T22:31:58.486Z","dependency_job_id":"92f3fb97-d4b0-4fb0-b2cf-7e6523a570c6","html_url":"https://github.com/PaulRBerg/prb-proxy","commit_stats":{"total_commits":368,"total_committers":5,"mean_commits":73.6,"dds":0.03260869565217395,"last_synced_commit":"e8d5198ecd43f566024d73f3ecd97e67adfaca3e"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulRBerg%2Fprb-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulRBerg%2Fprb-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulRBerg%2Fprb-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PaulRBerg%2Fprb-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PaulRBerg","download_url":"https://codeload.github.com/PaulRBerg/prb-proxy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247822992,"owners_count":21001985,"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":["blockchain","delegatecall","ethereum","prb-proxy","proxy","smart-contracts","solidity"],"created_at":"2024-10-03T10:28:14.544Z","updated_at":"2025-04-08T10:28:19.900Z","avatar_url":"https://github.com/PaulRBerg.png","language":"Solidity","funding_links":["https://3cities.xyz/#/pay?c=CAESFAKY9DMuOFdjE4Wzl2YyUFipPiSfIgICATICCAJaFURvbmF0aW9uIHRvIFBhdWwgQmVyZw","https://github.com/sponsors/PaulRBerg"],"categories":[],"sub_categories":[],"readme":"# PRBProxy [![Github Actions][gha-badge]][gha] [![Coverage][codecov-badge]][codecov] [![Foundry][foundry-badge]][foundry] [![License: MIT][license-badge]][license]\n\n[gha]: https://github.com/PaulRBerg/prb-proxy/actions\n[gha-badge]: https://github.com/PaulRBerg/prb-proxy/actions/workflows/ci.yml/badge.svg\n[codecov]: https://codecov.io/gh/PaulRBerg/prb-proxy\n[codecov-badge]: https://codecov.io/gh/PaulRBerg/prb-proxy/branch/main/graph/badge.svg?token=4YV6JCTO9R\n[foundry]: https://getfoundry.sh/\n[foundry-badge]: https://img.shields.io/badge/Built%20with-Foundry-FFDB1C.svg\n[license]: https://opensource.org/licenses/MIT\n[license-badge]: https://img.shields.io/badge/License-MIT-blue.svg\n\nPRBProxy is a **forwarding proxy that allows for the composition of Ethereum transactions on behalf of the contract owner**, acting as a smart wallet\nthat enables multiple contract calls within a single transaction. In Ethereum, externally owned accounts (EOAs) do not have this functionality because\nthey cannot perform delegate calls.\n\nSome key features of PRBProxy include:\n\n- Forwards calls with [`DELEGATECALL`][se-3667].\n- Uses [CREATE2][eip-1014] to deploy the proxies at deterministic addresses.\n- A unique registry system ensures that each user has a distinct proxy.\n- A plugin system enables the proxy to respond to callbacks.\n- An access control system permits third-party accounts (called \"envoys\") to call target contracts on behalf of the owner.\n- Reverts with custom errors rather than reason strings for more efficient error handling.\n- Comprehensive documentation via NatSpec comments.\n- Developed and tested using Foundry.\n\nOverall, PRBProxy is a powerful tool for transaction composition, providing numerous features and benefits not available through EOAs:\n\n1. **Fewer interactions**: bundling multiple actions together lowers the number of protocol interactions required.\n2. **Modularity**: establishing a clear distinction between the core business logic of your protocol and the potentially more intricate, peripheral\n   higher-level logic.\n3. **Extensibility without upgradeability**: users can delegate call to any arbitrary contracts, including those not even written yet.\n\n## Background\n\nThe concept of a forwarding proxy has gained popularity thanks to DappHub, the developer team behind the decentralized stablecoin\n[DAI](https://makerdao.com). DappHub created [DSProxy](https://github.com/dapphub/ds-proxy), a widely used tool that allows for the execution of\nmultiple contract calls in a single transaction. Major DeFi players like Maker, Balancer, and DeFi Saver all rely on DSProxy.\n\nHowever, as the Ethereum ecosystem has evolved since DSProxy's launch in 2017, the tool has become outdated. With significant improvements to the\nSolidity compiler and new EVM OPCODES, as well as the introduction of more user-friendly development environments like\n[Foundry](https://book.getfoundry.sh/), it was time for an update.\n\nEnter PRBProxy, the modern successor to DSProxy; a \"DSProxy 2.0\", if you will. It improves upon DSProxy in several ways:\n\n1. PRBProxy is deployed with [CREATE2][eip-1014], which allows clients to pre-compute the proxy contract's address.\n2. Front-running is not possible.\n3. The proxy contract itself has no storage, which reduces the risk of storage collisions and malicious attacks.\n4. The proxy owner is immutable, and so it cannot be changed during any `DELEGATECALL`.\n5. PRBProxy uses high-level Solidity code that is easier to comprehend and less prone to errors.\n6. PRBProxy offers more features than DSProxy, such as plugins.\n\nUsing CREATE2 eliminates the risk of a [chain reorg](https://en.bitcoin.it/wiki/Chain_Reorganization) overriding the proxy contract owner, making\nPRBProxy a more secure alternative to DSProxy. With DSProxy, users must wait for several blocks to be mined before assuming the contract is secure.\nHowever, PRBProxy eliminates this risk entirely, making it possible to safely send funds to the proxy before it is deployed.\n\n## Deployments\n\nPRBProxyRegistry is deployed on 10+ chains at 0x584009E9eDe26e212182c9745F5c000191296a78. A sortable, searchable list of all available chains can be\nfound at https://prbproxy.com/deployments. To request a deployment to a new chain, please open a GitHub issue. You can speed up the process by sending\nfunds to cover the deploy cost to the deployer account: 0x3Afb8fEDaC6429E2165E84CC43EeA7e42e6440fF.\n\n### ABIs\n\nThe ABIs can be found on https://prbproxy.com/abi, where they can be downloaded or copied to the clipboard in various formats, including:\n\n- Solidity interfaces\n- JSON ABIs, prettified\n- viem human readable ABIs\n\nAlternatively, you can:\n\n- Download the ABIs from the [releases](https://github.com/PaulRBerg/prb-proxy/releases) page\n- Copy the ABIs from [Etherscan](https://etherscan.io/address/0x584009E9eDe26e212182c9745F5c000191296a78)\n- Install [Foundry](https://getfoundry.sh/) and run `cast interface 0x584009E9eDe26e212182c9745F5c000191296a78`\n- Use one of the programmatic methods described below\n\n## Install\n\n### Node.js\n\nThis is the recommended approach.\n\nInstall PRBProxy using your favorite package manager, e.g., with Bun:\n\n```shell\nbun add @prb/proxy\n```\n\nThen, if you are using Foundry, you need to add this to your `remappings.txt` file:\n\n```text\n@prb/proxy/=node_modules/@prb/proxy/\n```\n\n### Git Submodules\n\nThis installation method is not recommended, but it is available for those who prefer it.\n\nFirst, install the submodule using Forge:\n\n```shell\nforge install --no-commit PaulRBerg/prb-proxy@release-v4\n```\n\nYour `.gitmodules` file should now contain the following entry:\n\n```toml\n[submodule \"lib/prb-proxy\"]\n  branch = \"release-v4\"\n  path = \"lib/prb-proxy\"\n  url = \"https://github.com/PaulRBerg/prb-proxy\"\n```\n\nFinally, add this to your `remappings.txt` file:\n\n```text\n@prb/proxy/=lib/prb-proxy/\n```\n\n## Usage\n\nProxies are deployed via PRBProxyRegistry. There are multiple deploy functions available:\n\n| Function                     | Description                                                                                              |\n| ---------------------------- | -------------------------------------------------------------------------------------------------------- |\n| `deploy`                     | Deploy a proxy for `msg.sender`                                                                          |\n| `deployFor`                  | Deploy a proxy for the provided `owner`                                                                  |\n| `deployAndExecute`           | Deploy a proxy for `msg.sender`, and delegate calls to the provided target                               |\n| `deployAndInstallPlugin`     | Deploy a proxy for `msg.sender`, and installs the provided plugin                                        |\n| `deployAndExecuteAndInstall` | Deploy a proxy for `msg.sender`, delegate calls to the provided target, and installs the provided plugin |\n\nOnce the proxy is deployed, you can start interacting with target contracts by calling the `execute` function on the proxy by passing the ABI-encoding\nfunction signatures and data.\n\n### No Upgradeability\n\nFor the avoidance of doubt, PRBProxy is not an upgradeable proxy[^1]. It is a \"forwarding\" proxy whose sole purpose is to delegate calls to target and\nplugin contracts.\n\nBoth PRBProxyRegistry and PRBProxy are immutable contracts. Their source code cannot be changed once deployed.\n\n### Targets and Plugins\n\nSee this repository's [wiki](https://github.com/PaulRBerg/prb-proxy/wiki) page for guidance on how to write targets and plugins.\n\n### Frontends\n\nIntegrating PRBProxy into a front-end app would work something like this:\n\n1. Begin by calling the `getProxy` function on the registry to determine if the user already has a proxy.\n2. If the user does not have a proxy, deploy one for them using one of the deploy methods outlined above.\n3. Interact with your desired target contract using the `execute` function.\n4. Install relevant plugins, which can make the proxy react to your protocol events.\n5. Going forward, treat the proxy address as the user of your system.\n\nHowever, this is just scratching the surface. For more examples of how to use PRBProxy in a frontend environment, check out the [Frontends][frontends]\nwiki. Additionally, Maker's developer guide, [Working with DSProxy][dsproxy-guide], provides an in-depth exploration of the proxy concept that can\nalso help you understand how to use PRBProxy. Just be sure to keep in mind the differences outlined throughout this document.\n\n## Security\n\nWhile I have strict standards for code quality and test coverage, and the code has been audited by third-party security researchers, using PRBProxy\nmay not be entirely risk-free.\n\n### Caveat Emptor\n\nPlease be aware that this software is experimental and is provided on an \"as is\" and \"as available\" basis. I do not offer any warranties, and I cannot\nbe held responsible for any direct or indirect loss resulting from the continued use of this codebase.\n\n### Contact\n\nIf you discover any bugs or security issues, please report them via [Telegram](https://t.me/PaulRBerg).\n\n## License\n\nThis project is licensed under MIT.\n\n\u003c!-- Links --\u003e\n\n[eip-1014]: https://eips.ethereum.org/EIPS/eip-1014\n[frontends]: https://github.com/PaulRBerg/prb-proxy/wiki/Frontends\n[se-3667]: https://ethereum.stackexchange.com/questions/3667/difference-between-call-callcode-and-delegatecall/3672\n[dsproxy-guide]:\n  https://github.com/makerdao/developerguides/blob/9ded1b68228e6cd70885f1326349c6bf087b9573/devtools/working-with-dsproxy/working-with-dsproxy.md\n\n\u003c!-- Footnotes --\u003e\n\n[^1]:\n    The term \"proxy\" can refer to different concepts in Ethereum, most notably upgradeable proxies, a design popularized by\n    [OpenZeppelin](https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies) that enables contract owners to upgrade the contract's logic. It's\n    critical to note that PRBProxy does not fall under this category of upgradeable proxies.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulrberg%2Fprb-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaulrberg%2Fprb-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulrberg%2Fprb-proxy/lists"}