139 lines
4.2 KiB
Solidity
139 lines
4.2 KiB
Solidity
// SPDX-License-Identifier: PROPRIETARY AND MIT
|
|
// Copyright (c) 2024-2026 Тарабанов Александр Викторович
|
|
// All rights reserved.
|
|
//
|
|
// This software is proprietary and confidential.
|
|
// Unauthorized copying, modification, or distribution is prohibited.
|
|
//
|
|
// For licensing inquiries: info@hb3-accelerator.com
|
|
// Website: https://hb3-accelerator.com
|
|
// GitHub: https://github.com/VC-HB3-Accelerator
|
|
|
|
pragma solidity ^0.8.20;
|
|
|
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
|
|
// ERC-4337 интерфейсы для тестирования
|
|
interface IPaymaster {
|
|
function validatePaymasterUserOp(
|
|
UserOperation calldata userOp,
|
|
bytes32 userOpHash,
|
|
uint256 maxCost
|
|
) external returns (bytes memory context, uint256 validationData);
|
|
|
|
function postOp(
|
|
PostOpMode mode,
|
|
bytes calldata context,
|
|
uint256 actualGasCost
|
|
) external;
|
|
}
|
|
|
|
struct UserOperation {
|
|
address sender;
|
|
uint256 nonce;
|
|
bytes initCode;
|
|
bytes callData;
|
|
uint256 callGasLimit;
|
|
uint256 verificationGasLimit;
|
|
uint256 preVerificationGas;
|
|
uint256 maxFeePerGas;
|
|
uint256 maxPriorityFeePerGas;
|
|
bytes paymasterAndData;
|
|
bytes signature;
|
|
}
|
|
|
|
enum PostOpMode {
|
|
opSucceeded,
|
|
opReverted,
|
|
postOpReverted
|
|
}
|
|
|
|
/**
|
|
* @title MockPaymaster
|
|
* @dev Mock контракт для тестирования ERC-4337 Paymaster функциональности
|
|
*/
|
|
contract MockPaymaster is IPaymaster {
|
|
using SafeERC20 for IERC20;
|
|
|
|
// События для тестирования
|
|
event PaymasterValidated(address indexed sender, uint256 maxCost);
|
|
event PostOpCalled(PostOpMode mode, uint256 actualGasCost);
|
|
event TokenReceived(address indexed token, uint256 amount);
|
|
|
|
// Статистика для тестирования
|
|
uint256 public totalValidations;
|
|
uint256 public totalPostOps;
|
|
mapping(address => uint256) public tokenReceived;
|
|
|
|
/**
|
|
* @dev Валидация UserOperation (всегда успешна для тестов)
|
|
*/
|
|
function validatePaymasterUserOp(
|
|
UserOperation calldata userOp,
|
|
bytes32 userOpHash,
|
|
uint256 maxCost
|
|
) external override returns (bytes memory context, uint256 validationData) {
|
|
// Используем userOpHash для избежания предупреждения
|
|
userOpHash;
|
|
totalValidations++;
|
|
emit PaymasterValidated(userOp.sender, maxCost);
|
|
|
|
// Возвращаем пустой контекст и 0 (успешная валидация)
|
|
return (abi.encode(userOp.sender, maxCost), 0);
|
|
}
|
|
|
|
/**
|
|
* @dev Post-operation обработка
|
|
*/
|
|
function postOp(
|
|
PostOpMode mode,
|
|
bytes calldata context,
|
|
uint256 actualGasCost
|
|
) external override {
|
|
// Используем context для избежания предупреждения
|
|
context;
|
|
totalPostOps++;
|
|
emit PostOpCalled(mode, actualGasCost);
|
|
}
|
|
|
|
/**
|
|
* @dev Получить токены (для тестирования)
|
|
*/
|
|
function receiveTokens(address tokenAddress, uint256 amount) external payable {
|
|
if (tokenAddress == address(0)) {
|
|
// Нативные токены
|
|
require(msg.value == amount, "Incorrect native amount");
|
|
} else {
|
|
// ERC20 токены
|
|
IERC20(tokenAddress).safeTransferFrom(msg.sender, address(this), amount);
|
|
}
|
|
|
|
tokenReceived[tokenAddress] += amount;
|
|
emit TokenReceived(tokenAddress, amount);
|
|
}
|
|
|
|
/**
|
|
* @dev Получить нативные токены
|
|
*/
|
|
receive() external payable {
|
|
tokenReceived[address(0)] += msg.value;
|
|
emit TokenReceived(address(0), msg.value);
|
|
}
|
|
|
|
/**
|
|
* @dev Получить статистику
|
|
*/
|
|
function getStats() external view returns (
|
|
uint256 validations,
|
|
uint256 postOps,
|
|
uint256 nativeReceived
|
|
) {
|
|
return (
|
|
totalValidations,
|
|
totalPostOps,
|
|
tokenReceived[address(0)]
|
|
);
|
|
}
|
|
}
|