Files
zk-account-abstraction/contracts/interfaces/UserOperation.sol
Dror Tirosh b4ce311e12 AA-142 N-11 Typographical errors (#219)
Co-authored-by: shahafn <shahaflol@gmail.com>
2023-02-09 17:22:30 +02:00

85 lines
3.4 KiB
Solidity

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.12;
/* solhint-disable no-inline-assembly */
/**
* User Operation struct
* @param sender the sender account of this request.
* @param nonce unique value the sender uses to verify it is not a replay.
* @param initCode if set, the account contract will be created by this constructor/
* @param callData the method call to execute on this account.
* @param callGasLimit the gas limit passed to the callData method call.
* @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.
* @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.
* @param maxFeePerGas same as EIP-1559 gas parameter.
* @param maxPriorityFeePerGas same as EIP-1559 gas parameter.
* @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.
* @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.
*/
struct UserOperation {
address sender;
uint256 nonce;
bytes initCode;
bytes callData;
uint256 callGasLimit;
uint256 verificationGasLimit;
uint256 preVerificationGas;
uint256 maxFeePerGas;
uint256 maxPriorityFeePerGas;
bytes paymasterAndData;
bytes signature;
}
/**
* Utility functions helpful when working with UserOperation structs.
*/
library UserOperationLib {
function getSender(UserOperation calldata userOp) internal pure returns (address) {
address data;
//read sender from userOp, which is first userOp member (saves 800 gas...)
assembly {data := calldataload(userOp)}
return address(uint160(data));
}
//relayer/block builder might submit the TX with higher priorityFee, but the user should not
// pay above what he signed for.
function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {
unchecked {
uint256 maxFeePerGas = userOp.maxFeePerGas;
uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;
if (maxFeePerGas == maxPriorityFeePerGas) {
//legacy mode (for networks that don't support basefee opcode)
return maxFeePerGas;
}
return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);
}
}
function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {
//lighter signature scheme. must match UserOp.ts#packUserOp
bytes calldata sig = userOp.signature;
// copy directly the userOp from calldata up to (but not including) the signature.
// this encoding depends on the ABI encoding of calldata, but is much lighter to copy
// than referencing each field separately.
assembly {
let ofs := userOp
let len := sub(sub(sig.offset, ofs), 32)
ret := mload(0x40)
mstore(0x40, add(ret, add(len, 32)))
mstore(ret, len)
calldatacopy(add(ret, 32), ofs, len)
}
}
function hash(UserOperation calldata userOp) internal pure returns (bytes32) {
return keccak256(pack(userOp));
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
}