Skip to content

Commit 7a0c3b6

Browse files
committed
recompile
1 parent 53ff9ae commit 7a0c3b6

File tree

8 files changed

+497
-9
lines changed

8 files changed

+497
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >=0.8.18;
3+
4+
import { IPRBProxy } from "./interfaces/IPRBProxy.sol";
5+
import { IPRBProxyPlugin } from "./interfaces/IPRBProxyPlugin.sol";
6+
import { IPRBProxyRegistry } from "./interfaces/IPRBProxyRegistry.sol";
7+
8+
/*
9+
10+
██████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██╗ ██╗██╗ ██╗
11+
██╔══██╗██╔══██╗██╔══██╗██╔══██╗██╔══██╗██╔═══██╗╚██╗██╔╝╚██╗ ██╔╝
12+
██████╔╝██████╔╝██████╔╝██████╔╝██████╔╝██║ ██║ ╚███╔╝ ╚████╔╝
13+
██╔═══╝ ██╔══██╗██╔══██╗██╔═══╝ ██╔══██╗██║ ██║ ██╔██╗ ╚██╔╝
14+
██║ ██║ ██║██████╔╝██║ ██║ ██║╚██████╔╝██╔╝ ██╗ ██║
15+
╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
16+
17+
*/
18+
19+
/// @title PRBProxy
20+
/// @dev See the documentation in {IPRBProxy}.
21+
contract PRBProxy is IPRBProxy {
22+
/*//////////////////////////////////////////////////////////////////////////
23+
CONSTANTS
24+
//////////////////////////////////////////////////////////////////////////*/
25+
26+
/// @inheritdoc IPRBProxy
27+
address public immutable override owner;
28+
29+
/// @inheritdoc IPRBProxy
30+
IPRBProxyRegistry public immutable override registry;
31+
32+
/*//////////////////////////////////////////////////////////////////////////
33+
CONSTRUCTOR
34+
//////////////////////////////////////////////////////////////////////////*/
35+
36+
/// @notice Creates the proxy by fetching the constructor params from the registry, optionally delegate calling
37+
/// to a target contract if one is provided.
38+
/// @dev The rationale of this approach is to have the proxy's CREATE2 address not depend on any constructor params.
39+
constructor() {
40+
registry = IPRBProxyRegistry(msg.sender);
41+
(address owner_, address target, bytes memory data) = registry.constructorParams();
42+
owner = owner_;
43+
if (target != address(0)) {
44+
_execute(target, data);
45+
}
46+
}
47+
48+
/*//////////////////////////////////////////////////////////////////////////
49+
FALLBACK FUNCTIONS
50+
//////////////////////////////////////////////////////////////////////////*/
51+
52+
/// @notice Fallback function used to run plugins.
53+
/// @dev WARNING: anyone can call this function and thus run any installed plugin.
54+
fallback(bytes calldata data) external payable returns (bytes memory response) {
55+
// Check if the function selector points to a known installed plugin.
56+
IPRBProxyPlugin plugin = registry.getPluginByOwner({ owner: owner, method: msg.sig });
57+
if (address(plugin) == address(0)) {
58+
revert PRBProxy_PluginNotInstalledForMethod({ caller: msg.sender, owner: owner, method: msg.sig });
59+
}
60+
61+
// Delegate call to the plugin.
62+
bool success;
63+
(success, response) = address(plugin).delegatecall(data);
64+
65+
// Log the plugin run.
66+
emit RunPlugin(plugin, data, response);
67+
68+
// Check if the call was successful or not.
69+
if (!success) {
70+
// If there is return data, the delegate call reverted with a reason or a custom error, which we bubble up.
71+
if (response.length > 0) {
72+
assembly {
73+
let returndata_size := mload(response)
74+
revert(add(32, response), returndata_size)
75+
}
76+
} else {
77+
revert PRBProxy_PluginReverted(plugin);
78+
}
79+
}
80+
}
81+
82+
/// @dev Called when `msg.value` is not zero and the call data is empty.
83+
receive() external payable { }
84+
85+
/*//////////////////////////////////////////////////////////////////////////
86+
USER-FACING NON-CONSTANT FUNCTIONS
87+
//////////////////////////////////////////////////////////////////////////*/
88+
89+
/// @inheritdoc IPRBProxy
90+
function execute(address target, bytes calldata data) external payable override returns (bytes memory response) {
91+
// Check that the caller is either the owner or an envoy with permission.
92+
if (owner != msg.sender) {
93+
bool permission = registry.getPermissionByOwner({ owner: owner, envoy: msg.sender, target: target });
94+
if (!permission) {
95+
revert PRBProxy_ExecutionUnauthorized({ owner: owner, caller: msg.sender, target: target });
96+
}
97+
}
98+
99+
// Delegate call to the target contract, and handle the response.
100+
response = _execute(target, data);
101+
}
102+
103+
/*//////////////////////////////////////////////////////////////////////////
104+
INTERNAL NON-CONSTANT FUNCTIONS
105+
//////////////////////////////////////////////////////////////////////////*/
106+
107+
/// @notice Executes a DELEGATECALL to the provided target with the provided data.
108+
/// @dev Shared logic between the constructor and the `execute` function.
109+
function _execute(address target, bytes memory data) internal returns (bytes memory response) {
110+
// Check that the target is a contract.
111+
if (target.code.length == 0) {
112+
revert PRBProxy_TargetNotContract(target);
113+
}
114+
115+
// Delegate call to the target contract.
116+
bool success;
117+
(success, response) = target.delegatecall(data);
118+
119+
// Log the execution.
120+
emit Execute(target, data, response);
121+
122+
// Check if the call was successful or not.
123+
if (!success) {
124+
// If there is return data, the delegate call reverted with a reason or a custom error, which we bubble up.
125+
if (response.length > 0) {
126+
assembly {
127+
// The length of the data is at `response`, while the actual data is at `response + 32`.
128+
let returndata_size := mload(response)
129+
revert(add(response, 32), returndata_size)
130+
}
131+
} else {
132+
revert PRBProxy_ExecutionReverted();
133+
}
134+
}
135+
}
136+
}

contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity >=0.8.18;
33

4-
import { IPRBProxy } from "@prb/proxy/src/interfaces/IPRBProxy.sol";
5-
import { IPRBProxyPlugin } from "@prb/proxy/src/interfaces/IPRBProxyPlugin.sol";
6-
import { IPRBProxyRegistry } from "@prb/proxy/src/interfaces/IPRBProxyRegistry.sol";
7-
import { PRBProxy } from "@prb/proxy/src/PRBProxy.sol";
4+
import { IPRBProxy } from "./interfaces/IPRBProxy.sol";
5+
import { IPRBProxyPlugin } from "./interfaces/IPRBProxyPlugin.sol";
6+
import { IPRBProxyRegistry } from "./interfaces/IPRBProxyRegistry.sol";
7+
import { PRBProxy } from "./PRBProxy.sol";
88

99
/// @author Modified from prb-proxy (https://github.com/PaulRBerg/prb-proxy/blob/main/src/PRBProxyRegistry.sol)
1010
/// @title PRBProxyRegistry

contracts/prebuilts/unaudited/checkout/TargetCheckout.sol

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import "../../../lib/CurrencyTransferLib.sol";
55
import "../../../eip/interface/IERC20.sol";
66

77
import { IPRBProxy } from "@prb/proxy/src/interfaces/IPRBProxy.sol";
8-
import "./interface/IPluginCheckout.sol";
8+
import "./interfaces/IPluginCheckout.sol";
99

1010
// $$\ $$\ $$\ $$\ $$\
1111
// $$ | $$ | \__| $$ | $$ |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >=0.8.4;
3+
4+
import { IPRBProxyPlugin } from "./IPRBProxyPlugin.sol";
5+
import { IPRBProxyRegistry } from "./IPRBProxyRegistry.sol";
6+
7+
/// @title IPRBProxy
8+
/// @notice Proxy contract to compose transactions on behalf of the owner.
9+
interface IPRBProxy {
10+
/*//////////////////////////////////////////////////////////////////////////
11+
ERRORS
12+
//////////////////////////////////////////////////////////////////////////*/
13+
14+
/// @notice Thrown when a target contract reverts without a specified reason.
15+
error PRBProxy_ExecutionReverted();
16+
17+
/// @notice Thrown when an unauthorized account tries to execute a delegate call.
18+
error PRBProxy_ExecutionUnauthorized(address owner, address caller, address target);
19+
20+
/// @notice Thrown when the fallback function fails to find an installed plugin for the method selector.
21+
error PRBProxy_PluginNotInstalledForMethod(address caller, address owner, bytes4 method);
22+
23+
/// @notice Thrown when a plugin execution reverts without a specified reason.
24+
error PRBProxy_PluginReverted(IPRBProxyPlugin plugin);
25+
26+
/// @notice Thrown when a non-contract address is passed as the target.
27+
error PRBProxy_TargetNotContract(address target);
28+
29+
/*//////////////////////////////////////////////////////////////////////////
30+
EVENTS
31+
//////////////////////////////////////////////////////////////////////////*/
32+
33+
/// @notice Emitted when a target contract is delegate called.
34+
event Execute(address indexed target, bytes data, bytes response);
35+
36+
/// @notice Emitted when a plugin is run for a provided method.
37+
event RunPlugin(IPRBProxyPlugin indexed plugin, bytes data, bytes response);
38+
39+
/*//////////////////////////////////////////////////////////////////////////
40+
CONSTANT FUNCTIONS
41+
//////////////////////////////////////////////////////////////////////////*/
42+
43+
/// @notice The address of the owner account or contract, which controls the proxy.
44+
function owner() external view returns (address);
45+
46+
/// @notice The address of the registry that has deployed this proxy.
47+
function registry() external view returns (IPRBProxyRegistry);
48+
49+
/*//////////////////////////////////////////////////////////////////////////
50+
NON-CONSTANT FUNCTIONS
51+
//////////////////////////////////////////////////////////////////////////*/
52+
53+
/// @notice Delegate calls to the provided target contract by forwarding the data. It returns the data it
54+
/// gets back, and bubbles up any potential revert.
55+
///
56+
/// @dev Emits an {Execute} event.
57+
///
58+
/// Requirements:
59+
/// - The caller must be either the owner or an envoy with permission.
60+
/// - `target` must be a contract.
61+
///
62+
/// @param target The address of the target contract.
63+
/// @param data Function selector plus ABI encoded data.
64+
/// @return response The response received from the target contract, if any.
65+
function execute(address target, bytes calldata data) external payable returns (bytes memory response);
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity >=0.8.4;
3+
4+
/// @title IPRBProxyPlugin
5+
/// @notice Interface for plugin contracts that can be installed on a proxy.
6+
/// @dev Plugins are contracts that enable the proxy to interact with and respond to calls from other contracts. These
7+
/// plugins are run via the proxy's fallback function.
8+
///
9+
/// This interface is meant to be directly inherited by plugin implementations.
10+
interface IPRBProxyPlugin {
11+
/// @notice Retrieves the methods implemented by the plugin.
12+
/// @dev The registry pulls these methods when installing the plugin.
13+
///
14+
/// Requirements:
15+
/// - The plugin must implement at least one method.
16+
///
17+
/// @return methods The array of the methods implemented by the plugin.
18+
function getMethods() external returns (bytes4[] memory methods);
19+
}

0 commit comments

Comments
 (0)