Skip to content

Checkout plugin and proxy #598

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open

Checkout plugin and proxy #598

wants to merge 10 commits into from

Conversation

kumaryash90
Copy link
Member

No description provided.

Copy link

codecov bot commented Jan 9, 2024

Codecov Report

Attention: 23 lines in your changes are missing coverage. Please review.

Comparison is base (2568498) 64.08% compared to head (53ff9ae) 64.14%.
Report is 7 commits behind head on main.

❗ Current head 53ff9ae differs from pull request most recent head 786154c. Consider uploading reports for the commit 786154c to get more accurate results

Files Patch % Lines
...ts/unaudited/checkout/PRBProxyRegistryModified.sol 53.19% 22 Missing ⚠️
...ts/prebuilts/unaudited/checkout/TargetCheckout.sol 95.65% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #598      +/-   ##
==========================================
+ Coverage   64.08%   64.14%   +0.06%     
==========================================
  Files         215      218       +3     
  Lines        6632     6708      +76     
==========================================
+ Hits         4250     4303      +53     
- Misses       2382     2405      +23     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

socket-security bot commented Jan 9, 2024

New and removed dependencies detected. Learn more about Socket for GitHub ↗︎

Package New capabilities Transitives Size Publisher
npm/@babel/code-frame@7.23.5 Transitive: environment +10 191 kB nicolo-ribaudo
npm/@eslint/eslintrc@2.1.4 filesystem, unsafe Transitive: environment, eval +26 3.73 MB eslintbot
npm/@isaacs/cliui@8.0.2 None +7 184 kB isaacs
npm/@noble/hashes@1.3.3 None 0 761 kB paulmillr
npm/@pkgjs/parseargs@0.11.0 None 0 74.2 kB oss-bot
npm/@thirdweb-dev/chains@0.1.62 environment, network 0 6.14 MB jnsdls
npm/@thirdweb-dev/sdk@4.0.25 environment, eval, network Transitive: filesystem +126 295 MB jnsdls
npm/@thirdweb-dev/storage@2.0.8 environment, network Transitive: filesystem +44 3.49 MB jnsdls
npm/acorn-walk@8.3.1 None 0 52.3 kB marijn
npm/acorn@8.11.3 None 0 531 kB marijn
npm/chai@4.4.0 None +7 923 kB chaijs
npm/eastasianwidth@0.2.0 None 0 13.6 kB komagata
npm/fastq@1.16.0 None +1 49.5 kB matteo.collina
npm/foreground-child@3.1.1 shell Transitive: environment, filesystem +7 189 kB isaacs
npm/glob@7.2.3 filesystem Transitive: environment +10 145 kB isaacs
npm/globals@13.24.0 None +1 163 kB sindresorhus
npm/jackspeak@2.3.6 environment +9 512 kB isaacs
npm/minipass@7.0.4 None 0 285 kB isaacs
npm/node-gyp-build@4.8.0 environment, filesystem 0 13.4 kB mafintosh
npm/path-scurry@1.10.1 filesystem +2 1.27 MB isaacs
npm/sucrase@3.35.0 Transitive: environment, filesystem, shell, unsafe +34 4.47 MB alangpierce
npm/yargs-parser@20.2.9 environment, filesystem 0 124 kB oss-bot

🚮 Removed packages: npm/@thirdweb-dev/chains@0.1.58, npm/@thirdweb-dev/sdk@4.0.16

View full report↗︎

@kumaryash90 kumaryash90 requested a review from jakeloo January 9, 2024 21:32
Comment on lines 53 to 66
function _execute(UserOp memory op) internal {
bool success;
if (op.currency == CurrencyTransferLib.NATIVE_TOKEN) {
(success, ) = op.target.call{ value: op.valueToSend }(op.data);
} else {
if (op.valueToSend != 0 && op.approvalRequired) {
IERC20(op.currency).approve(op.target, op.valueToSend);
}

(success, ) = op.target.call(op.data);
}

require(success, "Execution failed");
}

Check failure

Code scanning / Slither

Functions that send Ether to arbitrary destinations

TargetCheckout._execute(IPluginCheckout.UserOp) (contracts/prebuilts/unaudited/checkout/TargetCheckout.sol#53-66) sends eth to arbitrary user Dangerous calls: - (success,None) = op.target.call{value: op.valueToSend}(op.data) (contracts/prebuilts/unaudited/checkout/TargetCheckout.sol#56)
Comment on lines 53 to 66
function _execute(UserOp memory op) internal {
bool success;
if (op.currency == CurrencyTransferLib.NATIVE_TOKEN) {
(success, ) = op.target.call{ value: op.valueToSend }(op.data);
} else {
if (op.valueToSend != 0 && op.approvalRequired) {
IERC20(op.currency).approve(op.target, op.valueToSend);
}

(success, ) = op.target.call(op.data);
}

require(success, "Execution failed");
}

Check warning

Code scanning / Slither

Unused return

TargetCheckout._execute(IPluginCheckout.UserOp) (contracts/prebuilts/unaudited/checkout/TargetCheckout.sol#53-66) ignores return value by IERC20(op.currency).approve(op.target,op.valueToSend) (contracts/prebuilts/unaudited/checkout/TargetCheckout.sol#59)
Comment on lines 53 to 66
function _execute(UserOp memory op) internal {
bool success;
if (op.currency == CurrencyTransferLib.NATIVE_TOKEN) {
(success, ) = op.target.call{ value: op.valueToSend }(op.data);
} else {
if (op.valueToSend != 0 && op.approvalRequired) {
IERC20(op.currency).approve(op.target, op.valueToSend);
}

(success, ) = op.target.call(op.data);
}

require(success, "Execution failed");
}

Check warning

Code scanning / Slither

Low-level calls

Low level call in TargetCheckout._execute(IPluginCheckout.UserOp) (contracts/prebuilts/unaudited/checkout/TargetCheckout.sol#53-66): - (success,None) = op.target.call{value: op.valueToSend}(op.data) (contracts/prebuilts/unaudited/checkout/TargetCheckout.sol#56) - (success,None) = op.target.call(op.data) (contracts/prebuilts/unaudited/checkout/TargetCheckout.sol#62)
Comment on lines +217 to +250
function _installPlugin(IPRBProxyPlugin plugin) internal {
// Retrieve the methods to install.
bytes4[] memory methods = plugin.getMethods();

// The plugin must implement at least one method.
uint256 length = methods.length;
if (length == 0) {
revert PRBProxyRegistry_PluginWithZeroMethods(plugin);
}

// Install every method in the list.
address owner = msg.sender;
for (uint256 i = 0; i < length; ) {
// Check for collisions.
bytes4 method = methods[i];
if (address(_plugins[owner][method]) != address(0)) {
revert PRBProxyRegistry_PluginMethodCollision({
currentPlugin: _plugins[owner][method],
newPlugin: plugin,
method: method
});
}
_plugins[owner][method] = plugin;
unchecked {
i += 1;
}
}

// Set the methods in the reverse mapping.
_methods[owner][plugin] = methods;

// Log the plugin installation.
emit InstallPlugin(owner, _proxies[owner], plugin, methods);
}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities

Reentrancy in PRBProxyRegistryModified._installPlugin(IPRBProxyPlugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#217-250): External calls: - methods = plugin.getMethods() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#219) State variables written after the call(s): - _methods[owner][plugin] = methods (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#246) - _plugins[owner][method] = plugin (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#239)
Comment on lines +147 to +152
function deployAndInstallPlugin(
IPRBProxyPlugin plugin
) external onlyNonProxyOwner(msg.sender) returns (IPRBProxy proxy) {
proxy = _deploy({ owner: msg.sender, target: address(0), data: "" });
_installPlugin(plugin);
}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities

Reentrancy in PRBProxyRegistryModified.deployAndInstallPlugin(IPRBProxyPlugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#147-152): External calls: - proxy = _deploy({owner:msg.sender,target:address(0),data:}) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#150) - proxy = new PRBProxy() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#206) - _installPlugin(plugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#151) - methods = plugin.getMethods() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#219) State variables written after the call(s): - _installPlugin(plugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#151) - _methods[owner][plugin] = methods (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#246)
Comment on lines +198 to +214
function _deploy(address owner, address target, bytes memory data) internal returns (IPRBProxy proxy) {
// Use the address of the owner as the CREATE2 salt.
bytes32 salt = bytes32(abi.encodePacked(owner));

// Set the owner and empty out the target and the data to prevent reentrancy.
constructorParams = ConstructorParams({ owner: owner, target: target, data: data });

// Deploy the proxy with CREATE2.
proxy = new PRBProxy{ salt: salt }();
delete constructorParams;

// Associate the owner and the proxy.
_proxies[owner] = proxy;

// Log the creation of the proxy.
emit DeployProxy({ operator: msg.sender, owner: owner, proxy: proxy });
}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities

Reentrancy in PRBProxyRegistryModified._deploy(address,address,bytes) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#198-214): External calls: - proxy = new PRBProxy() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#206) State variables written after the call(s): - _proxies[owner] = proxy (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#210) - delete constructorParams (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#207)
Comment on lines +137 to +144
function deployAndExecuteAndInstallPlugin(
address target,
bytes calldata data,
IPRBProxyPlugin plugin
) external override onlyNonProxyOwner(msg.sender) returns (IPRBProxy proxy) {
proxy = _deploy({ owner: msg.sender, target: target, data: data });
_installPlugin(plugin);
}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities

Reentrancy in PRBProxyRegistryModified.deployAndExecuteAndInstallPlugin(address,bytes,IPRBProxyPlugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#137-144): External calls: - proxy = _deploy({owner:msg.sender,target:target,data:data}) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#142) - proxy = new PRBProxy() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#206) - _installPlugin(plugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#143) - methods = plugin.getMethods() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#219) State variables written after the call(s): - _installPlugin(plugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#143) - _methods[owner][plugin] = methods (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#246)
Comment on lines +137 to +144
function deployAndExecuteAndInstallPlugin(
address target,
bytes calldata data,
IPRBProxyPlugin plugin
) external override onlyNonProxyOwner(msg.sender) returns (IPRBProxy proxy) {
proxy = _deploy({ owner: msg.sender, target: target, data: data });
_installPlugin(plugin);
}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities

Reentrancy in PRBProxyRegistryModified.deployAndExecuteAndInstallPlugin(address,bytes,IPRBProxyPlugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#137-144): External calls: - proxy = _deploy({owner:msg.sender,target:target,data:data}) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#142) - proxy = new PRBProxy() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#206) - _installPlugin(plugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#143) - methods = plugin.getMethods() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#219) Event emitted after the call(s): - InstallPlugin(owner,_proxies[owner],plugin,methods) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#249) - _installPlugin(plugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#143)
Comment on lines +147 to +152
function deployAndInstallPlugin(
IPRBProxyPlugin plugin
) external onlyNonProxyOwner(msg.sender) returns (IPRBProxy proxy) {
proxy = _deploy({ owner: msg.sender, target: address(0), data: "" });
_installPlugin(plugin);
}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities

Reentrancy in PRBProxyRegistryModified.deployAndInstallPlugin(IPRBProxyPlugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#147-152): External calls: - proxy = _deploy({owner:msg.sender,target:address(0),data:}) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#150) - proxy = new PRBProxy() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#206) - _installPlugin(plugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#151) - methods = plugin.getMethods() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#219) Event emitted after the call(s): - InstallPlugin(owner,_proxies[owner],plugin,methods) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#249) - _installPlugin(plugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#151)
Comment on lines +217 to +250
function _installPlugin(IPRBProxyPlugin plugin) internal {
// Retrieve the methods to install.
bytes4[] memory methods = plugin.getMethods();

// The plugin must implement at least one method.
uint256 length = methods.length;
if (length == 0) {
revert PRBProxyRegistry_PluginWithZeroMethods(plugin);
}

// Install every method in the list.
address owner = msg.sender;
for (uint256 i = 0; i < length; ) {
// Check for collisions.
bytes4 method = methods[i];
if (address(_plugins[owner][method]) != address(0)) {
revert PRBProxyRegistry_PluginMethodCollision({
currentPlugin: _plugins[owner][method],
newPlugin: plugin,
method: method
});
}
_plugins[owner][method] = plugin;
unchecked {
i += 1;
}
}

// Set the methods in the reverse mapping.
_methods[owner][plugin] = methods;

// Log the plugin installation.
emit InstallPlugin(owner, _proxies[owner], plugin, methods);
}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities

Reentrancy in PRBProxyRegistryModified._installPlugin(IPRBProxyPlugin) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#217-250): External calls: - methods = plugin.getMethods() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#219) Event emitted after the call(s): - InstallPlugin(owner,_proxies[owner],plugin,methods) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#249)
Comment on lines +198 to +214
function _deploy(address owner, address target, bytes memory data) internal returns (IPRBProxy proxy) {
// Use the address of the owner as the CREATE2 salt.
bytes32 salt = bytes32(abi.encodePacked(owner));

// Set the owner and empty out the target and the data to prevent reentrancy.
constructorParams = ConstructorParams({ owner: owner, target: target, data: data });

// Deploy the proxy with CREATE2.
proxy = new PRBProxy{ salt: salt }();
delete constructorParams;

// Associate the owner and the proxy.
_proxies[owner] = proxy;

// Log the creation of the proxy.
emit DeployProxy({ operator: msg.sender, owner: owner, proxy: proxy });
}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities

Reentrancy in PRBProxyRegistryModified._deploy(address,address,bytes) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#198-214): External calls: - proxy = new PRBProxy() (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#206) Event emitted after the call(s): - DeployProxy({operator:msg.sender,owner:owner,proxy:proxy}) (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#213)
@@ -0,0 +1,251 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.18;

Check warning

Code scanning / Slither

Different pragma directives are used

Different versions of Solidity are used: - Version used: ['>=0.8.18', '>=0.8.4', '^0.8.0', '^0.8.1', '^0.8.10', '^0.8.11', '^0.8.12', '^0.8.2', '^0.8.4', '^0.8.8', '^0.8.9'] - >=0.8.18 (contracts/prebuilts/unaudited/checkout/PRBProxyRegistryModified.sol#2) - >=0.8.18 (lib/prb-proxy/src/PRBProxy.sol#2) - >=0.8.4 (lib/prb-proxy/src/interfaces/IPRBProxy.sol#2) - >=0.8.4 (lib/prb-proxy/src/interfaces/IPRBProxyPlugin.sol#2) - >=0.8.4 (lib/prb-proxy/src/interfaces/IPRBProxyRegistry.sol#2) - ^0.8.0 (contracts/base/ERC1155Base.sol#2) - ^0.8.0 (contracts/base/ERC1155DelayedReveal.sol#2) - ^0.8.0 (contracts/base/ERC1155Drop.sol#2) - ^0.8.0 (contracts/base/ERC1155LazyMint.sol#2) - ^0.8.0 (contracts/base/ERC1155SignatureMint.sol#2) - ^0.8.0 (contracts/base/ERC20Base.sol#2) - ^0.8.0 (contracts/base/ERC20Drop.sol#2) - ^0.8.0 (contracts/base/ERC20DropVote.sol#2) - ^0.8.0 (contracts/base/ERC20SignatureMint.sol#2) - ^0.8.0 (contracts/base/ERC20SignatureMintVote.sol#2) - ^0.8.0 (contracts/base/ERC20Vote.sol#2) - ^0.8.0 (contracts/base/ERC721Base.sol#2) - ^0.8.0 (contracts/base/ERC721DelayedReveal.sol#2) - ^0.8.0 (contracts/base/ERC721Drop.sol#2) - ^0.8.0 (contracts/base/ERC721LazyMint.sol#2) - ^0.8.0 (contracts/base/ERC721Multiwrap.sol#2) - ^0.8.0 (contracts/base/ERC721SignatureMint.sol#2) - ^0.8.0 (contracts/base/Staking1155Base.sol#2) - ^0.8.0 (contracts/base/Staking20Base.sol#2) - ^0.8.0 (contracts/base/Staking721Base.sol#2) - ^0.8.0 (contracts/eip/ERC1155.sol#2) - ^0.8.0 (contracts/eip/ERC1271.sol#2) - ^0.8.0 (contracts/eip/ERC165.sol#4) - ^0.8.0 (contracts/eip/interface/IERC1155.sol#2) - ^0.8.0 (contracts/eip/interface/IERC1155Enumerable.sol#2) - ^0.8.0 (contracts/eip/interface/IERC1155Metadata.sol#2) - ^0.8.0 (contracts/eip/interface/IERC1155Receiver.sol#4) - ^0.8.0 (contracts/eip/interface/IERC1155Supply.sol#2) - ^0.8.0 (contracts/eip/interface/IERC165.sol#4) - ^0.8.0 (contracts/eip/interface/IERC20.sol#2) - ^0.8.0 (contracts/eip/interface/IERC20Metadata.sol#2) - ^0.8.0 (contracts/eip/interface/IERC20Permit.sol#4) - ^0.8.0 (contracts/eip/interface/IERC2981.sol#2) - ^0.8.0 (contracts/eip/interface/IERC721.sol#4) - ^0.8.0 (contracts/eip/interface/IERC721Enumerable.sol#2) - ^0.8.0 (contracts/eip/interface/IERC721Metadata.sol#2) - ^0.8.0 (contracts/eip/interface/IERC721Receiver.sol#4) - ^0.8.0 (contracts/eip/interface/IERC721Supply.sol#2) - ^0.8.0 (contracts/eip/queryable/ERC721AStorage.sol#3) - ^0.8.0 (contracts/eip/queryable/ERC721A__Initializable.sol#2) - ^0.8.0 (contracts/eip/queryable/ERC721A__InitializableStorage.sol#3) - ^0.8.0 (contracts/extension/AppURI.sol#2) - ^0.8.0 (contracts/extension/BatchMintMetadata.sol#2) - ^0.8.0 (contracts/extension/BurnToClaim.sol#2) - ^0.8.0 (contracts/extension/ContractMetadata.sol#2) - ^0.8.0 (contracts/extension/DelayedReveal.sol#2) - ^0.8.0 (contracts/extension/Drop.sol#2) - ^0.8.0 (contracts/extension/Drop1155.sol#2) - ^0.8.0 (contracts/extension/DropSinglePhase.sol#2) - ^0.8.0 (contracts/extension/DropSinglePhase1155.sol#2) - ^0.8.0 (contracts/extension/Initializable.sol#2) - ^0.8.0 (contracts/extension/LazyMint.sol#2) - ^0.8.0 (contracts/extension/LazyMintWithTier.sol#2) - ^0.8.0 (contracts/extension/Multicall.sol#2) - ^0.8.0 (contracts/extension/NFTMetadata.sol#2) - ^0.8.0 (contracts/extension/OperatorFilterToggle.sol#2) - ^0.8.0 (contracts/extension/OperatorFilterer.sol#2) - ^0.8.0 (contracts/extension/OperatorFiltererUpgradeable.sol#2) - ^0.8.0 (contracts/extension/Ownable.sol#2) - ^0.8.0 (contracts/extension/Permissions.sol#2) - ^0.8.0 (contracts/extension/PermissionsEnumerable.sol#2) - ^0.8.0 (contracts/extension/PlatformFee.sol#2) - ^0.8.0 (contracts/extension/PrimarySale.sol#2) - ^0.8.0 (contracts/extension/Proxy.sol#2) - ^0.8.0 (contracts/extension/ProxyForUpgradeable.sol#2) - ^0.8.0 (contracts/extension/Royalty.sol#2) - ^0.8.0 (contracts/extension/SignatureAction.sol#2) - ^0.8.0 (contracts/extension/SignatureActionUpgradeable.sol#2) - ^0.8.0 (contracts/extension/SignatureMintERC1155.sol#2) - ^0.8.0 (contrac
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant