Skip to content

Commit

Permalink
Bump safe-core-protocol version
Browse files Browse the repository at this point in the history
  • Loading branch information
mmv08 committed Sep 28, 2023
1 parent 6d911b9 commit 4f2c59c
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 129 deletions.
2 changes: 1 addition & 1 deletion contracts/contracts/Base.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ abstract contract BasePlugin is ISafeProtocolPlugin {
metadataHash = keccak256(metadata.encode());
}

function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
function supportsInterface(bytes4 interfaceId) external pure virtual override returns (bool) {
return interfaceId == type(ISafeProtocolPlugin).interfaceId || interfaceId == type(IERC165).interfaceId;
}

Expand Down
43 changes: 16 additions & 27 deletions contracts/contracts/ERC4337Plugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
pragma solidity ^0.8.18;
import {ISafeProtocolPlugin, ISafeProtocolFunctionHandler} from "@safe-global/safe-core-protocol/contracts/interfaces/Modules.sol";

import {ISafeProtocolManager} from "@safe-global/safe-core-protocol/contracts/interfaces/Manager.sol";
import {SafeTransaction, SafeRootAccess, SafeProtocolAction} from "@safe-global/safe-core-protocol/contracts/DataTypes.sol";
import {BasePluginWithEventMetadata, PluginMetadata, MetadataProviderType} from "./Base.sol";
import {MODULE_TYPE_PLUGIN} from "@safe-global/safe-core-protocol/contracts/common/Constants.sol";
import {BasePlugin, BasePluginWithEventMetadata, PluginMetadata, MetadataProviderType} from "./Base.sol";

import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";

interface ISafe {
function isOwner(address owner) external view returns (bool);
Expand All @@ -26,33 +30,11 @@ interface ISafe {
uint8 operation
) external returns (bool success, bytes memory returnData);

function enablePlugin(address plugin, bool allowRootAccess) external;
function enablePlugin(address plugin, uint8 permissions) external;

function setFunctionHandler(bytes4 selector, address functionHandler) external;
}

interface ISafeProtocolManager {
/**
* @notice This function allows enabled plugins to execute non-delegate call transactions thorugh a Safe.
* It should validate the status of the plugin through the registry and allows only listed and non-flagged integrations to execute transactions.
* @param safe Address of a Safe account
* @param transaction SafeTransaction instance containing payload information about the transaction
* @return data Array of bytes types returned upon the successful execution of all the actions. The size of the array will be the same as the size of the actions
* in case of succcessful execution. Empty if the call failed.
*/
function executeTransaction(ISafe safe, SafeTransaction calldata transaction) external returns (bytes[] memory data);

/**
* @notice This function allows enabled plugins to execute delegate call transactions thorugh a Safe.
* It should validate the status of the plugin through the registry and allows only listed and non-flagged integrations to execute transactions.
* @param safe Address of a Safe account
* @param rootAccess SafeTransaction instance containing payload information about the transaction
* @return data Arbitrary length bytes data returned upon the successful execution. The size of the array will be the same as the size of the actions
* in case of succcessful execution. Empty if the call failed.
*/
function executeRootAccess(ISafe safe, SafeRootAccess calldata rootAccess) external returns (bytes memory data);
}

struct UserOperation {
address sender;
uint256 nonce;
Expand Down Expand Up @@ -103,6 +85,7 @@ contract ERC4337Plugin is ISafeProtocolFunctionHandler, BasePluginWithEventMetad
require(msg.sender == address(PLUGIN_ADDRESS));
address payable safeAddress = payable(msg.sender);
ISafe safe = ISafe(safeAddress);

require(safe.execTransactionFromModule(to, value, data, 0), "tx failed");
}

Expand All @@ -120,10 +103,9 @@ contract ERC4337Plugin is ISafeProtocolFunctionHandler, BasePluginWithEventMetad
require(address(this) != PLUGIN_ADDRESS, "Only delegatecall");

ISafe safe = ISafe(address(this));

safe.setFallbackHandler(address(SAFE_PROTOCOL_MANAGER));
safe.enableModule(address(SAFE_PROTOCOL_MANAGER));
safe.enablePlugin(PLUGIN_ADDRESS, false);
safe.enablePlugin(PLUGIN_ADDRESS, MODULE_TYPE_PLUGIN);
safe.setFunctionHandler(this.validateUserOp.selector, PLUGIN_ADDRESS);
safe.setFunctionHandler(this.execTransaction.selector, PLUGIN_ADDRESS);
}
Expand All @@ -138,7 +120,14 @@ contract ERC4337Plugin is ISafeProtocolFunctionHandler, BasePluginWithEventMetad
override(BasePluginWithEventMetadata, ISafeProtocolFunctionHandler)
returns (uint256 providerType, bytes memory location)
{
providerType = uint256(MetadataProviderType.Contract);
providerType = uint256(MetadataProviderType.Event);
location = abi.encode(address(this));
}

function supportsInterface(bytes4 interfaceId) external pure override(BasePlugin, IERC165) returns (bool) {
return
interfaceId == type(ISafeProtocolPlugin).interfaceId ||
interfaceId == type(IERC165).interfaceId ||
interfaceId == type(ISafeProtocolFunctionHandler).interfaceId;
}
}
7 changes: 3 additions & 4 deletions contracts/contracts/Plugins.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity ^0.8.18;

import {BasePluginWithEventMetadata, PluginMetadata} from "./Base.sol";
import {ISafe} from "@safe-global/safe-core-protocol/contracts/interfaces/Accounts.sol";
import {ISafeProtocolManager} from "@safe-global/safe-core-protocol/contracts/interfaces/Manager.sol";
import {SafeTransaction, SafeProtocolAction} from "@safe-global/safe-core-protocol/contracts/DataTypes.sol";
import {_getFeeCollectorRelayContext, _getFeeTokenRelayContext, _getFeeRelayContext} from "@gelatonetwork/relay-context/contracts/GelatoRelayContext.sol";
Expand Down Expand Up @@ -47,12 +46,12 @@ contract RelayPlugin is BasePluginWithEventMetadata {
emit MaxFeeUpdated(msg.sender, token, maxFee);
}

function payFee(ISafeProtocolManager manager, ISafe safe, uint256 nonce) internal {
function payFee(ISafeProtocolManager manager, address safe, uint256 nonce) internal {
address feeCollector = _getFeeCollectorRelayContext();
address feeToken = _getFeeTokenRelayContext();
uint256 fee = _getFeeRelayContext();
SafeProtocolAction[] memory actions = new SafeProtocolAction[](1);
uint256 maxFee = maxFeePerToken[address(safe)][feeToken];
uint256 maxFee = maxFeePerToken[safe][feeToken];
if (fee > maxFee) revert FeeTooHigh(feeToken, fee);
if (feeToken == NATIVE_TOKEN || feeToken == address(0)) {
// If the native token is used for fee payment, then we directly send the fees to the fee collector
Expand Down Expand Up @@ -81,7 +80,7 @@ contract RelayPlugin is BasePluginWithEventMetadata {
if (!success) revert RelayExecutionFailure(data);
}

function executeFromPlugin(ISafeProtocolManager manager, ISafe safe, bytes calldata data) external {
function executeFromPlugin(ISafeProtocolManager manager, address safe, bytes calldata data) external {
if (trustedOrigin != address(0) && msg.sender != trustedOrigin) revert UntrustedOrigin(msg.sender);

relayCall(address(safe), data);
Expand Down
5 changes: 2 additions & 3 deletions contracts/contracts/RecoveryWithDelayPlugin.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.18;
import {ISafe} from "@safe-global/safe-core-protocol/contracts/interfaces/Accounts.sol";
import {ISafeProtocolManager} from "@safe-global/safe-core-protocol/contracts/interfaces/Manager.sol";
import {BasePluginWithEventMetadata, PluginMetadata} from "./Base.sol";
import {SafeTransaction, SafeRootAccess, SafeProtocolAction} from "@safe-global/safe-core-protocol/contracts/DataTypes.sol";
Expand Down Expand Up @@ -76,13 +75,13 @@ contract RecoveryWithDelayPlugin is BasePluginWithEventMetadata {
*/
function executeFromPlugin(
ISafeProtocolManager manager,
ISafe safe,
address safe,
address prevOwner,
address oldOwner,
address newOwner,
uint256 nonce
) external returns (bytes memory data) {
bytes32 txHash = getTransactionHash(address(manager), address(safe), prevOwner, oldOwner, newOwner, nonce);
bytes32 txHash = getTransactionHash(address(manager), safe, prevOwner, oldOwner, newOwner, nonce);
Announcement memory announcement = announcements[txHash];

if (announcement.executed) {
Expand Down
11 changes: 5 additions & 6 deletions contracts/contracts/WhitelistPlugin.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.18;
import {ISafe} from "@safe-global/safe-core-protocol/contracts/interfaces/Accounts.sol";

import {ISafeProtocolManager} from "@safe-global/safe-core-protocol/contracts/interfaces/Manager.sol";
import {SafeTransaction, SafeProtocolAction} from "@safe-global/safe-core-protocol/contracts/DataTypes.sol";
import {BasePluginWithEventMetadata, PluginMetadata} from "./Base.sol";
Expand Down Expand Up @@ -41,19 +41,18 @@ contract WhitelistPlugin is BasePluginWithEventMetadata {
*/
function executeFromPlugin(
ISafeProtocolManager manager,
ISafe safe,
address safe,
SafeTransaction calldata safetx
) external returns (bytes[] memory data) {
address safeAddress = address(safe);
// Only Safe owners are allowed to execute transactions to whitelisted accounts.
if (!(OwnerManager(safeAddress).isOwner(msg.sender))) {
revert CallerIsNotOwner(safeAddress, msg.sender);
if (!(OwnerManager(safe).isOwner(msg.sender))) {
revert CallerIsNotOwner(safe, msg.sender);
}

SafeProtocolAction[] memory actions = safetx.actions;
uint256 length = actions.length;
for (uint256 i = 0; i < length; i++) {
if (!whitelistedAddresses[safeAddress][actions[i].to]) revert AddressNotWhiteListed(actions[i].to);
if (!whitelistedAddresses[safe][actions[i].to]) revert AddressNotWhiteListed(actions[i].to);
}
// Test: Any tx that updates whitelist of this contract should be blocked
(data) = manager.executeTransaction(safe, safetx);
Expand Down
146 changes: 73 additions & 73 deletions contracts/package.json
Original file line number Diff line number Diff line change
@@ -1,74 +1,74 @@
{
"name": "@safe-global/safe-core-protocol-demo",
"version": "0.1.0-alpha.0",
"description": "'Demo of Safe{Core} Protocol contracts",
"main": "dist/index.js",
"repository": "git@github.com:5afe/safe-core-protocol-demo.git",
"author": "safe.global",
"license": "LGPL-3.0",
"scripts": {
"build": "hardhat compile",
"test": "hardhat test",
"coverage": "hardhat coverage",
"fmt:sol": "prettier 'contracts/**/*.sol' -w",
"fmt:ts": "prettier 'test/**/*.ts' -w",
"fmt": "yarn fmt:ts && yarn fmt:sol",
"lint": "yarn lint:sol && yarn lint:ts",
"lint:sol": "solhint 'contracts/**/*.sol'",
"lint:ts": "eslint 'test/**/*.ts' --max-warnings 0 --fix",
"typechain": "TS_NODE_TRANSPILE_ONLY=true hardhat typechain",
"postinstall": "yarn typechain",
"deploy": "hardhat deploy --network",
"register-plugin": "hardhat register-plugin --network",
"list-plugins": "hardhat list-plugins --network",
"prepack": "yarn build"
},
"devDependencies": {
"@gelatonetwork/relay-context": "^2.1.0",
"@nomicfoundation/hardhat-chai-matchers": "^2.0.2",
"@nomicfoundation/hardhat-ethers": "^3.0.4",
"@nomicfoundation/hardhat-network-helpers": "^1.0.9",
"@nomicfoundation/hardhat-toolbox": "^3.0.0",
"@nomicfoundation/hardhat-verify": "^1.1.1",
"@openzeppelin/contracts": "^4.9.3",
"@safe-global/mock-contract": "^4.1.0",
"@safe-global/safe-contracts": "^1.4.1-build.0",
"@safe-global/safe-core-protocol": "^0.2.1-alpha.0",
"@safe-global/safe-singleton-factory": "^1.0.15",
"@typechain/ethers-v6": "^0.5.0",
"@typechain/hardhat": "^9.0.0",
"@types/chai": "^4.3.6",
"@types/mocha": ">=9.1.0",
"@types/node": ">=20.5.9",
"@types/yargs": "^17.0.24",
"@typescript-eslint/eslint-plugin": "^6.6.0",
"@typescript-eslint/parser": "^6.6.0",
"chai": "^4.3.8",
"dotenv": "^16.3.1",
"eslint": "^8.48.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-prettier": "^5.0.0",
"ethers": "^6.7.1",
"hardhat": "^2.17.2",
"hardhat-deploy": "^0.11.37",
"hardhat-gas-reporter": "^1.0.8",
"hardhat-typechain": "^0.3.5",
"prettier": "^3.0.3",
"prettier-plugin-solidity": "^1.1.3",
"solhint": "^3.6.2",
"solhint-plugin-prettier": "^0.0.5",
"solidity-coverage": "^0.8.4",
"ts-node": ">=8.0.0",
"typechain": "^8.3.1",
"typescript": "~5.2.2",
"yargs": "^17.7.2"
},
"files": [
"contracts",
"dist",
"scripts",
"test",
"artifacts"
]
}
"name": "@safe-global/safe-core-protocol-demo",
"version": "0.1.0-alpha.0",
"description": "'Demo of Safe{Core} Protocol contracts",
"main": "dist/index.js",
"repository": "git@github.com:5afe/safe-core-protocol-demo.git",
"author": "safe.global",
"license": "LGPL-3.0",
"scripts": {
"build": "hardhat compile",
"test": "hardhat test",
"coverage": "hardhat coverage",
"fmt:sol": "prettier 'contracts/**/*.sol' -w",
"fmt:ts": "prettier 'test/**/*.ts' -w",
"fmt": "yarn fmt:ts && yarn fmt:sol",
"lint": "yarn lint:sol && yarn lint:ts",
"lint:sol": "solhint 'contracts/**/*.sol'",
"lint:ts": "eslint 'test/**/*.ts' --max-warnings 0 --fix",
"typechain": "TS_NODE_TRANSPILE_ONLY=true hardhat typechain",
"postinstall": "yarn typechain",
"deploy": "hardhat deploy --network",
"register-plugin": "hardhat register-plugin --network",
"list-plugins": "hardhat list-plugins --network",
"prepack": "yarn build"
},
"devDependencies": {
"@gelatonetwork/relay-context": "^2.1.0",
"@nomicfoundation/hardhat-chai-matchers": "^2.0.2",
"@nomicfoundation/hardhat-ethers": "^3.0.4",
"@nomicfoundation/hardhat-network-helpers": "^1.0.9",
"@nomicfoundation/hardhat-toolbox": "^3.0.0",
"@nomicfoundation/hardhat-verify": "^1.1.1",
"@openzeppelin/contracts": "^4.9.3",
"@safe-global/mock-contract": "^4.1.0",
"@safe-global/safe-contracts": "^1.4.1-build.0",
"@safe-global/safe-core-protocol": "^0.3.0-alpha.1",
"@safe-global/safe-singleton-factory": "^1.0.15",
"@typechain/ethers-v6": "^0.5.0",
"@typechain/hardhat": "^9.0.0",
"@types/chai": "^4.3.6",
"@types/mocha": ">=9.1.0",
"@types/node": ">=20.5.9",
"@types/yargs": "^17.0.24",
"@typescript-eslint/eslint-plugin": "^6.6.0",
"@typescript-eslint/parser": "^6.6.0",
"chai": "^4.3.8",
"dotenv": "^16.3.1",
"eslint": "^8.48.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-prettier": "^5.0.0",
"ethers": "^6.7.1",
"hardhat": "^2.17.2",
"hardhat-deploy": "^0.11.37",
"hardhat-gas-reporter": "^1.0.8",
"hardhat-typechain": "^0.3.5",
"prettier": "^3.0.3",
"prettier-plugin-solidity": "^1.1.3",
"solhint": "^3.6.2",
"solhint-plugin-prettier": "^0.0.5",
"solidity-coverage": "^0.8.4",
"ts-node": ">=8.0.0",
"typechain": "^8.3.1",
"typescript": "~5.2.2",
"yargs": "^17.7.2"
},
"files": [
"contracts",
"dist",
"scripts",
"test",
"artifacts"
]
}
16 changes: 14 additions & 2 deletions contracts/src/utils/builder.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { AddressLike } from "ethers";
import { SafeRootAccess, SafeTransaction } from "./dataTypes";

export const buildSingleTx = (address: AddressLike, value: bigint, data: string, nonce: bigint, metadataHash: Uint8Array | string): SafeTransaction => {
export const buildSingleTx = (
address: AddressLike,
value: bigint,
data: string,
nonce: bigint,
metadataHash: Uint8Array | string,
): SafeTransaction => {
return {
actions: [
{
Expand All @@ -15,7 +21,13 @@ export const buildSingleTx = (address: AddressLike, value: bigint, data: string,
};
};

export const buildRootTx = (address: AddressLike, value: bigint, data: string, nonce: bigint, metadataHash: Uint8Array | string): SafeRootAccess => {
export const buildRootTx = (
address: AddressLike,
value: bigint,
data: string,
nonce: bigint,
metadataHash: Uint8Array | string,
): SafeRootAccess => {
return {
action: {
to: address,
Expand Down
8 changes: 4 additions & 4 deletions contracts/src/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export const SENTINEL_MODULES = "0x0000000000000000000000000000000000000001";

export enum IntegrationType {
Plugin,
Hooks,
FunctionHandler,
export enum ModuleType {
Plugin = 1,
FunctionHandler = 2,
Hooks = 4,
}

export enum ExecutionType {
Expand Down
Loading

0 comments on commit 4f2c59c

Please sign in to comment.