• Stars
    star
    271
  • Rank 151,717 (Top 3 %)
  • Language
    Solidity
  • License
    MIT License
  • Created about 3 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Proxy contract to compose Ethereum transactions

PRBProxy Github Actions Coverage Foundry License: MIT

PRBProxy is a forwarding proxy that allows for the composition of Ethereum transactions on behalf of the contract owner, acting as a smart wallet that enables multiple contract calls within a single transaction. In Ethereum, externally owned accounts (EOAs) do not have this functionality because they cannot perform delegate calls.

Some key features of PRBProxy include:

  • Forwards calls with DELEGATECALL.
  • Uses CREATE2 to deploy the proxies at deterministic addresses.
  • A unique registry system ensures that each user has a distinct proxy.
  • A plugin system enables the proxy to respond to callbacks.
  • An access control system permits third-party accounts (called "envoys") to call target contracts on behalf of the owner.
  • Reverts with custom errors rather than reason strings for more efficient error handling.
  • Comprehensive documentation via NatSpec comments.
  • Developed and tested using Foundry.

Overall, PRBProxy is a powerful tool for transaction composition, providing numerous features and benefits not available through EOAs:

  1. Fewer interactions: bundling multiple actions together lowers the number of protocol interactions required.
  2. Modularity: establishing a clear distinction between the core business logic of your protocol and the potentially more intricate, peripheral higher-level logic.
  3. Extensibility without upgradeability: users can delegate call to any arbitrary contracts, including those not even written yet.

Background

The concept of a forwarding proxy has gained popularity thanks to DappHub, the developer team behind the decentralized stablecoin DAI. DappHub created DSProxy, a widely used tool that allows for the execution of multiple contract calls in a single transaction. Major DeFi players like Maker, Balancer, and DeFi Saver all rely on DSProxy.

However, as the Ethereum ecosystem has evolved since DSProxy's launch in 2017, the tool has become outdated. With significant improvements to the Solidity compiler and new EVM OPCODES, as well as the introduction of more user-friendly development environments like Foundry, it was time for an update.

Enter PRBProxy, the modern successor to DSProxy; a "DSProxy 2.0", if you will. It improves upon DSProxy in several ways:

  1. PRBProxy is deployed with CREATE2, which allows clients to pre-compute the proxy contract's address.
  2. Front-running is not possible.
  3. The proxy contract itself has no storage, which reduces the risk of storage collisions and malicious attacks.
  4. The proxy owner is immutable, and so it cannot be changed during any DELEGATECALL.
  5. PRBProxy uses high-level Solidity code that is easier to comprehend and less prone to errors.
  6. PRBProxy offers more features than DSProxy, such as plugins.

Using CREATE2 eliminates the risk of a chain reorg overriding the proxy contract owner, making PRBProxy a more secure alternative to DSProxy. With DSProxy, users must wait for several blocks to be mined before assuming the contract is secure. However, PRBProxy eliminates this risk entirely, making it possible to safely send funds to the proxy before it is deployed.

Deployments

PRBProxyRegistry is deployed on 10+ chains at 0x584009E9eDe26e212182c9745F5c000191296a78. A sortable, searchable list of all available chains can be found 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 funds to cover the deploy cost to the deployer account: 0x3Afb8fEDaC6429E2165E84CC43EeA7e42e6440fF.

ABIs

The ABIs can be found on https://prbproxy.com/abi, where they can be downloaded or copied to the clipboard in various formats, including:

  • Solidity interfaces
  • JSON ABIs, prettified
  • viem human readable ABIs

Alternatively, you can:

  • Download the ABIs from the releases page.
  • Copy the ABIs from Etherscan.
  • Install Foundry and run cast interface 0x584009E9eDe26e212182c9745F5c000191296a78.
  • Use one of the programmatic methods described below.

Install

You can get access to the Solidity code and the ABIs programmatically.

Foundry

First, run the install step:

forge install PaulRBerg/prb-proxy@release-v4

Your .gitmodules file should now contain the following entry:

[submodule "lib/prb-proxy"]
  branch = "release-v4"
  path = "lib/prb-proxy"
  url = "https://github.com/PaulRBerg/prb-proxy"

Finally, add this to your remappings.txt file:

prb-proxy/=lib/prb-proxy/

Hardhat

PRBProxy is available as an npm package:

pnpm add @prb/proxy

Usage

Proxies are deployed via PRBProxyRegistry. There are multiple deploy functions available:

Function Description
deploy Deploy a proxy for msg.sender
deployFor Deploy a proxy for the provided owner
deployAndExecute Deploy a proxy for msg.sender, and delegate calls to the provided target
deployAndInstallPlugin Deploy a proxy for msg.sender, and installs the provided plugin
deployAndExecuteAndInstall Deploy a proxy for msg.sender, delegate calls to the provided target, and installs the provided plugin

Once the proxy is deployed, you can start interacting with target contracts by calling the execute function on the proxy by passing the ABI-encoding function signatures and data.

No Upgradeability

For the avoidance of doubt, PRBProxy is not an upgradeable proxy1. It is a "forwarding" proxy whose sole purpose is to delegate calls to target and plugin contracts.

Both PRBProxyRegistry and PRBProxy are immutable contracts. Their source code cannot be changed once deployed.

Targets and Plugins

See this repository's wiki page for guidance on how to write targets and plugins.

Frontends

Integrating PRBProxy into a front-end app would work something like this:

  1. Begin by calling the getProxy function on the registry to determine if the user already has a proxy.
  2. If the user does not have a proxy, deploy one for them using one of the deploy methods outlined above.
  3. Interact with your desired target contract using the execute function.
  4. Install relevant plugins, which can make the proxy react to your protocol events.
  5. Going forward, treat the proxy address as the user of your system.

However, this is just scratching the surface. For more examples of how to use PRBProxy in a frontend environment, check out the Frontends wiki. Additionally, Maker's developer guide, Working with DSProxy, provides an in-depth exploration of the proxy concept that can also help you understand how to use PRBProxy. Just be sure to keep in mind the differences outlined throughout this document.

Security

While I have strict standards for code quality and test coverage, and the code has been audited by third-party security researchers, using PRBProxy may not be entirely risk-free.

Caveat Emptor

Please 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 be held responsible for any direct or indirect loss resulting from the continued use of this codebase.

Contact

If you discover any bugs or security issues, please report them via Telegram.

License

This project is licensed under MIT.

Footnotes

  1. The term "proxy" can refer to different concepts in Ethereum, most notably upgradeable proxies, a design popularized by OpenZeppelin that enables contract owners to upgrade the contract's logic. It's critical to note that PRBProxy does not fall under this category of upgradeable proxies. ↩

More Repositories

1

hardhat-template

Hardhat-based template for developing Solidity smart contracts
TypeScript
1,958
star
2

prb-math

Solidity library for advanced fixed-point math
Solidity
876
star
3

foundry-template

Foundry-based template for developing Solidity smart contracts
Solidity
560
star
4

prb-test

Modern collection of testing assertions and logging utilities for Solidity
Solidity
181
star
5

prb-contracts

Off-the-shelf Solidity smart contracts
Solidity
132
star
6

multisol

CLI application for verifying Solidity contracts on Etherscan
Rust
113
star
7

rust-template

A template for developing Rust projects, with sensible defaults
Rust
84
star
8

awesome-zkp-starter-pack

A curated collection of links for zero-knowledge proof cryptography used in blockchains
70
star
9

btt-examples

Examples for Branching Tree Technique, a simple specification framework for writing structured Solidity tests
Solidity
58
star
10

evm-bn

Convert fixed-point numbers to ethers big numbers and vice-versa.
TypeScript
49
star
11

check-same-sign

Gas golfing the most gas efficient way to check if two integers have the same sign in Solidity
Solidity
46
star
12

foundry-multibuild

GitHub Action for building a Foundry project with a range of Solidity versions
Shell
39
star
13

hardhat-packager

Hardhat plugin for preparing the contract artifacts and the TypeChain bindings for registry deployment
TypeScript
35
star
14

ethsum

Simple Ethereum address checksum tool
JavaScript
33
star
15

solplate

Simple utility for generating boilerplate Solidity contracts
Rust
32
star
16

typescript-template

A template for developing TypeScript project, with sensible defaults
TypeScript
32
star
17

awesome-many-worlds

Curated collection of educational materials on the many-worlds interpretation of quantum mechanics
25
star
18

github-labels

GitHub labels to use across repositories
Shell
21
star
19

CoinMarketCap-Desktop

A simple desktop wrapper for CoinMarketCap
JavaScript
21
star
20

cryptfolio-scripts

A collection of Google Apps Script custom functions for tracking crypto portfolios in Google Sheets
JavaScript
20
star
21

erc2212

Reference implementation for ERC-2212
JavaScript
12
star
22

unchecked-counter

Solidity counter type that bypasses checked arithmetic
Solidity
12
star
23

create2-repro

Repo to reproduce the inconsistent CREATE2 behavior in Foundry
Solidity
11
star
24

contractz

Sketchbook for my Ethereum contracts
Solidity
11
star
25

modlizer

Struggling with iOS design patterns? Embrace Modlizer
Swift
11
star
26

defi-types

TypeChain bindings for DeFi protocols
Solidity
10
star
27

dyi-crypto-taxes

Spreadsheet templates and practical tips and tricks for doing your taxes alone
10
star
28

abdk-gas-estimations

Gas estimations for ADBKMath64x64
Solidity
9
star
29

rust-book-annotations

My absorption of the Rust Book
Rust
8
star
30

javascript-template

A template for developing JavaScript projects, with sensible defaults
JavaScript
7
star
31

typescript-monorepo-template

Dummy monorepo set up with Typescript and Yarn Workspaces
TypeScript
4
star
32

tft

Browser extension that prevents typos by asking you to double-check the content before posting a long tweet
JavaScript
3
star
33

foundry-expect-emit-bug

Repo to reproduce the bug I ran into while writing tests with Foundry
Solidity
3
star
34

cea-contracts

Base smart contracts used in the default template of Create Eth App
JavaScript
3
star
35

my-eth-app

Default boilerplate code generated by create-eth-app
HTML
3
star
36

hardhat-prb

Hardhat plugins to complement the PRB smart contract libraries
TypeScript
3
star
37

react-hooks

React Hooks to be shared across my personal projects and packages
JavaScript
2
star
38

flipper-ui

The frontend app for the users of Flipper.
JavaScript
2
star
39

web3-react-blobs

Blobs of web3-react code used in the Sablier Interface
JavaScript
2
star
40

forge-coverage-bug

Repo to reproduce the bug in the forge coverage command
Solidity
2
star
41

PaulRBerg.github.io

My personal website
HTML
2
star
42

xstate-useActor-bug

xstate useActor bug
TypeScript
2
star
43

vscode-dictionary

Personal dictionary for vscode-spell-checker
2
star
44

prb-proxy-frontend

Landing page for PRBProxy
TypeScript
2
star
45

eslint-config

Eslint config to be shared across my personal projects and packages
JavaScript
2
star
46

test-foundry-template

Solidity
2
star
47

rage-stream

Rage stream functionality added to Sablier
TypeScript
1
star
48

airdropx

Firebase backend for the AirdropX Telegram bot
JavaScript
1
star
49

learn-plasma-rss

RSS feed for Plasma resources
JavaScript
1
star
50

paulrberg-labelsync

Dummy repo for label-sync.com
1
star
51

sketchpad

Personal repo for learning, logs and constants
JavaScript
1
star
52

cea-template

The official base template for Create Eth App.
HTML
1
star
53

hardhat-ignition-basic

Dummy project for going through the [email protected] basic tutorial
TypeScript
1
star
54

buidler-invalid-opcode

Reproduces the ganache-cli invalid opcode bug
TypeScript
1
star
55

yarn-rc34-error

Dummy project to reproduce the errors I encountered with [email protected]
JavaScript
1
star
56

ethiasi

Landing page for the first Ethereum event in Iasi, Romania
CSS
1
star
57

ethereum-signatures-progress

A collection of links and resources I collected in order to implement EIP-191 and EIP-712 into geth.
1
star
58

codebase-go

Personal repo for learning, logs and constants related to golang.
Go
1
star
59

dfe

Browser extension that hides the price of Ether
JavaScript
1
star