-
Notifications
You must be signed in to change notification settings - Fork 555
Checkout plugin and proxy #598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 7 commits
ccc4f30
5aa972a
1c4cfab
ef7f6cd
6933b23
955c131
c24e576
53ff9ae
7a0c3b6
786154c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,251 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity >=0.8.18; | ||
|
||
import { IPRBProxy } from "@prb/proxy/src/interfaces/IPRBProxy.sol"; | ||
import { IPRBProxyPlugin } from "@prb/proxy/src/interfaces/IPRBProxyPlugin.sol"; | ||
import { IPRBProxyRegistry } from "@prb/proxy/src/interfaces/IPRBProxyRegistry.sol"; | ||
import { PRBProxy } from "@prb/proxy/src/PRBProxy.sol"; | ||
|
||
/// @author Modified from prb-proxy (https://github.com/PaulRBerg/prb-proxy/blob/main/src/PRBProxyRegistry.sol) | ||
/// @title PRBProxyRegistry | ||
/// @dev See the documentation in {IPRBProxyRegistry}. | ||
contract PRBProxyRegistryModified is IPRBProxyRegistry { | ||
/*////////////////////////////////////////////////////////////////////////// | ||
CONSTANTS | ||
//////////////////////////////////////////////////////////////////////////*/ | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
string public constant override VERSION = "4.0.2"; | ||
|
||
/// @dev Magic value to override target permissions. Holders can execute on any target. | ||
address public constant MAGIC_TARGET = address(0x42); | ||
|
||
/*////////////////////////////////////////////////////////////////////////// | ||
USER-FACING STORAGE | ||
//////////////////////////////////////////////////////////////////////////*/ | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
ConstructorParams public override constructorParams; | ||
|
||
/*////////////////////////////////////////////////////////////////////////// | ||
INTERNAL STORAGE | ||
//////////////////////////////////////////////////////////////////////////*/ | ||
|
||
mapping(address owner => mapping(IPRBProxyPlugin plugin => bytes4[] methods)) internal _methods; | ||
|
||
mapping(address owner => mapping(address envoy => mapping(address target => bool permission))) | ||
internal _permissions; | ||
|
||
mapping(address owner => mapping(bytes4 method => IPRBProxyPlugin plugin)) internal _plugins; | ||
|
||
mapping(address owner => IPRBProxy proxy) internal _proxies; | ||
|
||
/*////////////////////////////////////////////////////////////////////////// | ||
MODIFIERS | ||
//////////////////////////////////////////////////////////////////////////*/ | ||
|
||
/// @notice Checks that the caller has a proxy. | ||
modifier onlyCallerWithProxy() { | ||
if (address(_proxies[msg.sender]) == address(0)) { | ||
revert PRBProxyRegistry_UserDoesNotHaveProxy(msg.sender); | ||
} | ||
_; | ||
} | ||
|
||
/// @notice Check that the user does not have a proxy. | ||
modifier onlyNonProxyOwner(address user) { | ||
IPRBProxy proxy = _proxies[user]; | ||
if (address(proxy) != address(0)) { | ||
revert PRBProxyRegistry_UserHasProxy(user, proxy); | ||
} | ||
_; | ||
} | ||
|
||
/*////////////////////////////////////////////////////////////////////////// | ||
USER-FACING CONSTANT FUNCTIONS | ||
//////////////////////////////////////////////////////////////////////////*/ | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function getMethodsByOwner(address owner, IPRBProxyPlugin plugin) external view returns (bytes4[] memory methods) { | ||
methods = _methods[owner][plugin]; | ||
} | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function getMethodsByProxy( | ||
IPRBProxy proxy, | ||
IPRBProxyPlugin plugin | ||
) external view returns (bytes4[] memory methods) { | ||
methods = _methods[proxy.owner()][plugin]; | ||
} | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function getPermissionByOwner( | ||
address owner, | ||
address envoy, | ||
address target | ||
) external view returns (bool permission) { | ||
permission = _permissions[owner][envoy][target] || _permissions[owner][envoy][MAGIC_TARGET]; | ||
} | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function getPermissionByProxy( | ||
IPRBProxy proxy, | ||
address envoy, | ||
address target | ||
) external view returns (bool permission) { | ||
permission = _permissions[proxy.owner()][envoy][target] || _permissions[proxy.owner()][envoy][MAGIC_TARGET]; | ||
} | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function getPluginByOwner(address owner, bytes4 method) external view returns (IPRBProxyPlugin plugin) { | ||
plugin = _plugins[owner][method]; | ||
} | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function getPluginByProxy(IPRBProxy proxy, bytes4 method) external view returns (IPRBProxyPlugin plugin) { | ||
plugin = _plugins[proxy.owner()][method]; | ||
} | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function getProxy(address user) external view returns (IPRBProxy proxy) { | ||
proxy = _proxies[user]; | ||
} | ||
|
||
/*////////////////////////////////////////////////////////////////////////// | ||
USER-FACING NON-CONSTANT FUNCTIONS | ||
//////////////////////////////////////////////////////////////////////////*/ | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function deploy() external override onlyNonProxyOwner(msg.sender) returns (IPRBProxy proxy) { | ||
proxy = _deploy({ owner: msg.sender, target: address(0), data: "" }); | ||
} | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function deployAndExecute( | ||
address target, | ||
bytes calldata data | ||
) external override onlyNonProxyOwner(msg.sender) returns (IPRBProxy proxy) { | ||
proxy = _deploy({ owner: msg.sender, target: target, data: data }); | ||
} | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function deployFor(address user) external override onlyNonProxyOwner(user) returns (IPRBProxy proxy) { | ||
proxy = _deploy({ owner: user, target: address(0), data: "" }); | ||
} | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
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); | ||
} | ||
Comment on lines
+137
to
+144
Check noticeCode 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
Check noticeCode 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)
|
||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function deployAndInstallPlugin( | ||
IPRBProxyPlugin plugin | ||
) external onlyNonProxyOwner(msg.sender) returns (IPRBProxy proxy) { | ||
proxy = _deploy({ owner: msg.sender, target: address(0), data: "" }); | ||
_installPlugin(plugin); | ||
} | ||
Comment on lines
+147
to
+152
Check noticeCode 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
+147
to
+152
Check noticeCode 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)
|
||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function installPlugin(IPRBProxyPlugin plugin) external override onlyCallerWithProxy { | ||
_installPlugin(plugin); | ||
} | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function setPermission(address envoy, address target, bool permission) external override onlyCallerWithProxy { | ||
address owner = msg.sender; | ||
_permissions[owner][envoy][target] = permission; | ||
emit SetPermission(owner, _proxies[owner], envoy, target, permission); | ||
} | ||
|
||
/// @inheritdoc IPRBProxyRegistry | ||
function uninstallPlugin(IPRBProxyPlugin plugin) external override onlyCallerWithProxy { | ||
// Retrieve the methods originally installed by this plugin. | ||
address owner = msg.sender; | ||
bytes4[] memory methods = _methods[owner][plugin]; | ||
|
||
// The plugin must be a known, previously installed plugin. | ||
uint256 length = methods.length; | ||
if (length == 0) { | ||
revert PRBProxyRegistry_PluginUnknown(plugin); | ||
} | ||
|
||
// Uninstall every method in the list. | ||
for (uint256 i = 0; i < length; ) { | ||
delete _plugins[owner][methods[i]]; | ||
unchecked { | ||
i += 1; | ||
} | ||
} | ||
|
||
// Remove the methods from the reverse mapping. | ||
delete _methods[owner][plugin]; | ||
|
||
// Log the plugin uninstallation. | ||
emit UninstallPlugin(owner, _proxies[owner], plugin, methods); | ||
} | ||
|
||
/*////////////////////////////////////////////////////////////////////////// | ||
INTERNAL NON-CONSTANT FUNCTIONS | ||
//////////////////////////////////////////////////////////////////////////*/ | ||
|
||
/// @dev See the documentation for the user-facing functions that call this internal function. | ||
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 }); | ||
} | ||
Comment on lines
+198
to
+214
Check noticeCode 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
+198
to
+214
Check noticeCode 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)
|
||
|
||
/// @dev See the documentation for the user-facing functions that call this internal function. | ||
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); | ||
} | ||
Comment on lines
+217
to
+250
Check noticeCode 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
+217
to
+250
Check noticeCode 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)
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.11; | ||
|
||
// $$\ $$\ $$\ $$\ $$\ | ||
// $$ | $$ | \__| $$ | $$ | | ||
// $$$$$$\ $$$$$$$\ $$\ $$$$$$\ $$$$$$$ |$$\ $$\ $$\ $$$$$$\ $$$$$$$\ | ||
// \_$$ _| $$ __$$\ $$ |$$ __$$\ $$ __$$ |$$ | $$ | $$ |$$ __$$\ $$ __$$\ | ||
// $$ | $$ | $$ |$$ |$$ | \__|$$ / $$ |$$ | $$ | $$ |$$$$$$$$ |$$ | $$ | | ||
// $$ |$$\ $$ | $$ |$$ |$$ | $$ | $$ |$$ | $$ | $$ |$$ ____|$$ | $$ | | ||
// \$$$$ |$$ | $$ |$$ |$$ | \$$$$$$$ |\$$$$$\$$$$ |\$$$$$$$\ $$$$$$$ | | ||
// \____/ \__| \__|\__|\__| \_______| \_____\____/ \_______|\_______/ | ||
|
||
import { IPRBProxyPlugin } from "@prb/proxy/src/interfaces/IPRBProxyPlugin.sol"; | ||
|
||
import "./TargetCheckout.sol"; | ||
|
||
contract PluginCheckout is IPRBProxyPlugin, TargetCheckout { | ||
function getMethods() external pure override returns (bytes4[] memory) { | ||
bytes4[] memory methods = new bytes4[](4); | ||
methods[0] = this.withdraw.selector; | ||
methods[1] = this.execute.selector; | ||
methods[2] = this.swapAndExecute.selector; | ||
methods[3] = this.approveSwapRouter.selector; | ||
return methods; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.11; | ||
|
||
import "../../../lib/CurrencyTransferLib.sol"; | ||
import "../../../eip/interface/IERC20.sol"; | ||
|
||
import { IPRBProxy } from "@prb/proxy/src/interfaces/IPRBProxy.sol"; | ||
import "./interface/IPluginCheckout.sol"; | ||
|
||
// $$\ $$\ $$\ $$\ $$\ | ||
// $$ | $$ | \__| $$ | $$ | | ||
// $$$$$$\ $$$$$$$\ $$\ $$$$$$\ $$$$$$$ |$$\ $$\ $$\ $$$$$$\ $$$$$$$\ | ||
// \_$$ _| $$ __$$\ $$ |$$ __$$\ $$ __$$ |$$ | $$ | $$ |$$ __$$\ $$ __$$\ | ||
// $$ | $$ | $$ |$$ |$$ | \__|$$ / $$ |$$ | $$ | $$ |$$$$$$$$ |$$ | $$ | | ||
// $$ |$$\ $$ | $$ |$$ |$$ | $$ | $$ |$$ | $$ | $$ |$$ ____|$$ | $$ | | ||
// \$$$$ |$$ | $$ |$$ |$$ | \$$$$$$$ |\$$$$$\$$$$ |\$$$$$$$\ $$$$$$$ | | ||
// \____/ \__| \__|\__|\__| \_______| \_____\____/ \_______|\_______/ | ||
|
||
contract TargetCheckout is IPluginCheckout { | ||
mapping(address => bool) public isApprovedRouter; | ||
|
||
function withdraw(address _token, uint256 _amount) external { | ||
require(msg.sender == IPRBProxy(address(this)).owner(), "Not authorized"); | ||
|
||
CurrencyTransferLib.transferCurrency(_token, address(this), msg.sender, _amount); | ||
} | ||
|
||
function approveSwapRouter(address _swapRouter, bool _toApprove) external { | ||
require(msg.sender == IPRBProxy(address(this)).owner(), "Not authorized"); | ||
require(_swapRouter != address(0), "Zero address"); | ||
|
||
isApprovedRouter[_swapRouter] = _toApprove; | ||
} | ||
|
||
function execute(UserOp memory op) external { | ||
require(_canExecute(op, msg.sender), "Not authorized"); | ||
|
||
_execute(op); | ||
} | ||
|
||
function swapAndExecute(UserOp memory op, UserOp memory swapOp) external { | ||
require(isApprovedRouter[swapOp.target], "Invalid router address"); | ||
require(_canExecute(op, msg.sender), "Not authorized"); | ||
|
||
_execute(swapOp); | ||
_execute(op); | ||
} | ||
|
||
// ================================================= | ||
// =============== Internal functions ============== | ||
// ================================================= | ||
|
||
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 failureCode 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)
Check warningCode 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)
Check warningCode 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)
|
||
|
||
function _canExecute(UserOp memory op, address caller) internal view returns (bool) { | ||
address owner = IPRBProxy(address(this)).owner(); | ||
if (owner != caller) { | ||
bool permission = IPRBProxy(address(this)).registry().getPermissionByOwner({ | ||
owner: owner, | ||
envoy: caller, | ||
target: op.target | ||
}); | ||
|
||
return permission; | ||
} | ||
|
||
return true; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity ^0.8.11; | ||
|
||
interface IPluginCheckout { | ||
/** | ||
* @notice Details of the transaction to execute on target contract. | ||
* | ||
* @param target Address to send the transaction to | ||
* | ||
* @param currency Represents both native token and erc20 token | ||
* | ||
* @param approvalRequired If need to approve erc20 to the target contract | ||
* | ||
* @param valueToSend Transaction value to send - both native and erc20 | ||
* | ||
* @param data Transaction calldata | ||
*/ | ||
struct UserOp { | ||
address target; | ||
address currency; | ||
bool approvalRequired; | ||
uint256 valueToSend; | ||
bytes data; | ||
} | ||
|
||
function execute(UserOp calldata op) external; | ||
|
||
function swapAndExecute(UserOp calldata op, UserOp memory swapOp) external; | ||
} |
Check warning
Code scanning / Slither
Different pragma directives are used