From 066904d6a2bf4acb0566c9a47e399a6b28a8b815 Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Thu, 15 Aug 2024 14:47:40 +0200 Subject: [PATCH] Check in RIP-7560 related contracts --- contracts/interfaces/IRip7560Account.sol | 22 +++++++++++ contracts/interfaces/IRip7560EntryPoint.sol | 9 +++++ contracts/interfaces/IRip7560Paymaster.sol | 40 ++++++++++++++++++++ contracts/interfaces/IRip7560Transaction.sol | 20 ++++++++++ contracts/utils/RIP7560Utils.sol | 39 +++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 contracts/interfaces/IRip7560Account.sol create mode 100644 contracts/interfaces/IRip7560EntryPoint.sol create mode 100644 contracts/interfaces/IRip7560Paymaster.sol create mode 100644 contracts/interfaces/IRip7560Transaction.sol create mode 100644 contracts/utils/RIP7560Utils.sol diff --git a/contracts/interfaces/IRip7560Account.sol b/contracts/interfaces/IRip7560Account.sol new file mode 100644 index 0000000..45610bd --- /dev/null +++ b/contracts/interfaces/IRip7560Account.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +/** + * @title IRip7560Account + * @dev Interface for the account contract. + */ +interface IRip7560Account { + /** + * account validation function. + * This method must call RIP7560Utils.accountAcceptTransaction to accept the transaction. + * Any other return value (or revert) will be considered as a rejection of the transaction. + * @param version - transaction encoding version RIP7560Utils.VERSION + * @param txHash - transaction hash to check the signature against + * @param transaction - encoded transaction + */ + function validateTransaction( + uint256 version, + bytes32 txHash, + bytes calldata transaction + ) external; +} diff --git a/contracts/interfaces/IRip7560EntryPoint.sol b/contracts/interfaces/IRip7560EntryPoint.sol new file mode 100644 index 0000000..d9b9e61 --- /dev/null +++ b/contracts/interfaces/IRip7560EntryPoint.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +interface IRip7560EntryPoint { + function acceptAccount(uint256 validAfter, uint256 validUntil) external; + function sigFailAccount(uint256 validAfter, uint256 validUntil) external; + function acceptPaymaster(uint256 validAfter, uint256 validUntil, bytes calldata context) external; + function sigFailPaymaster(uint256 validAfter, uint256 validUntil, bytes calldata context) external; +} diff --git a/contracts/interfaces/IRip7560Paymaster.sol b/contracts/interfaces/IRip7560Paymaster.sol new file mode 100644 index 0000000..fc2bf8c --- /dev/null +++ b/contracts/interfaces/IRip7560Paymaster.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +/** + * @title IRip7560Paymaster + * @dev Interface for the paymaster contract. + */ +interface IRip7560Paymaster { + + /** + * paymaster validation function. + * This method must call RIP7560Utils.paymasterAcceptTransaction to accept paying for the transaction. + * Any other return value (or revert) will be considered as a rejection of the transaction. + * @param version - transaction encoding version RIP7560Utils.VERSION + * @param txHash - transaction hash to check the signature against + * @param transaction - encoded transaction + */ + function validatePaymasterTransaction( + uint256 version, + bytes32 txHash, + bytes calldata transaction) + external; + + + /** + * paymaster post transaction function. + * This method is called after the transaction has been executed - if the validation function returned a context + * @dev revert in this method will cause the account execution function to revert too + * (but the reverted transaction will still get on-chain and be paid for) + * @param success - true if the transaction was successful, false otherwise + * @param actualGasCost - the actual gas cost of the transaction + * @param context - context data returned by validatePaymasterTransaction + */ + function postPaymasterTransaction( + bool success, + uint256 actualGasCost, + bytes calldata context + ) external; + +} diff --git a/contracts/interfaces/IRip7560Transaction.sol b/contracts/interfaces/IRip7560Transaction.sol new file mode 100644 index 0000000..b7533c8 --- /dev/null +++ b/contracts/interfaces/IRip7560Transaction.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +struct RIP7560TransactionStruct { + address sender; + uint256 nonce; + uint256 validationGasLimit; + uint256 paymasterValidationGasLimit; + uint256 postOpGasLimit; + uint256 callGasLimit; + uint256 maxFeePerGas; + uint256 maxPriorityFeePerGas; + uint256 builderFee; + address paymaster; + bytes paymasterData; + address deployer; + bytes deployerData; + bytes callData; + bytes signature; +} diff --git a/contracts/utils/RIP7560Utils.sol b/contracts/utils/RIP7560Utils.sol new file mode 100644 index 0000000..4afe28d --- /dev/null +++ b/contracts/utils/RIP7560Utils.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +import "../interfaces/IRip7560EntryPoint.sol"; +import "../interfaces/IRip7560Transaction.sol"; + +address constant ENTRY_POINT = 0x0000000000000000000000000000000000007560; + +library RIP7560Utils { + + //struct version, as defined in RIP-7560 + uint constant VERSION = 0; + + function decodeTransaction(uint256 version, bytes calldata transaction) internal pure returns (RIP7560TransactionStruct memory) { + require(version == VERSION, "RIP7560Utils: unsupported version"); + return abi.decode(transaction, (RIP7560TransactionStruct)); + } + + function accountAcceptTransaction( + uint48 validAfter, + uint48 validUntil + ) internal { + (bool success,) = ENTRY_POINT.call( + abi.encodeCall(IRip7560EntryPoint.acceptAccount, (validAfter, validUntil)) + ); + require(success); + } + + function paymasterAcceptTransaction( + bytes memory context, + uint256 validAfter, + uint256 validUntil + ) internal { + (bool success,) = ENTRY_POINT.call( + abi.encodeCall(IRip7560EntryPoint.acceptPaymaster, (validAfter, validUntil, context)) + ); + require(success); + } +}