Skip to content
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

[N24] Naming suggestions #80

Merged
merged 2 commits into from
Mar 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions contracts/EntryPoint.sol
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ contract EntryPoint is StakeManager {

//call wallet.validateUserOp, and validate that it paid as needed.
// return actual value sent from wallet to "this"
function _validateWalletPrepayment(uint256 opIndex, UserOperation calldata op, bytes32 requestId, uint256 requiredPrefund, PaymentMode paymentMode) internal returns (uint256 gasUsedByValidateUserOp, uint256 prefund) {
function _validateWalletPrepayment(uint256 opIndex, UserOperation calldata op, bytes32 requestId, uint256 requiredPrefund, PaymentMode paymentMode) internal returns (uint256 gasUsedByValidateWalletPrepayment, uint256 prefund) {
unchecked {
uint256 preGas = gasleft();
_createSenderIfNeeded(op);
Expand Down Expand Up @@ -237,12 +237,12 @@ contract EntryPoint is StakeManager {
} else {
prefund = 0;
}
gasUsedByValidateUserOp = preGas - gasleft();
gasUsedByValidateWalletPrepayment = preGas - gasleft();
}
}

//validate paymaster.validatePaymasterUserOp
function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, bytes32 requestId, uint256 requiredPreFund, uint256 gasUsedByValidateUserOp) internal view returns (bytes memory context) {
function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, bytes32 requestId, uint256 requiredPreFund, uint256 gasUsedByValidateWalletPrepayment) internal view returns (bytes memory context) {
unchecked {
//validate a paymaster has enough stake (including for payment for this TX)
// NOTE: when submitting a batch, caller has to make sure a paymaster has enough stake to cover
Expand All @@ -251,7 +251,7 @@ contract EntryPoint is StakeManager {
revert FailedOp(opIndex, op.paymaster, "not enough stake");
}
//no pre-pay from paymaster
uint256 gas = op.verificationGas - gasUsedByValidateUserOp;
uint256 gas = op.verificationGas - gasUsedByValidateWalletPrepayment;
try IPaymaster(op.paymaster).validatePaymasterUserOp{gas : gas}(op, requestId, requiredPreFund) returns (bytes memory _context){
context = _context;
} catch Error(string memory revertReason) {
Expand All @@ -268,19 +268,19 @@ contract EntryPoint is StakeManager {
uint256 maxGasValues = userOp.preVerificationGas | userOp.verificationGas |
userOp.callGas | userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;
require(maxGasValues < type(uint120).max, "gas values overflow");
uint256 gasUsedByValidateUserOp;
uint256 gasUsedByValidateWalletPrepayment;
uint256 requiredPreFund;
(requiredPreFund, paymentMode) = _getPaymentInfo(userOp);

(gasUsedByValidateUserOp, prefund) = _validateWalletPrepayment(opIndex, userOp, requestId, requiredPreFund, paymentMode);
(gasUsedByValidateWalletPrepayment, prefund) = _validateWalletPrepayment(opIndex, userOp, requestId, requiredPreFund, paymentMode);

//a "marker" where wallet opcode validation is done and paymaster opcode validation is about to start
// (used only by off-chain simulateValidation)
uint256 marker = block.number;
(marker);

if (paymentMode == PaymentMode.paymasterStake) {
(context) = _validatePaymasterPrepayment(opIndex, userOp, requestId, requiredPreFund, gasUsedByValidateUserOp);
(context) = _validatePaymasterPrepayment(opIndex, userOp, requestId, requiredPreFund, gasUsedByValidateWalletPrepayment);
} else {
context = "";
}
Expand Down
5 changes: 3 additions & 2 deletions contracts/IWallet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ interface IWallet {
* Must validate the signature and nonce
* @param userOp the operation that is about to be executed.
* @param requestId hash of the user's request data. can be used as the basis for signature.
* @param requiredPrefund the minimum amount to transfer to the sender(entryPoint) to be able to make the call.
* @param missingWalletFunds missing funds on the wallet's deposit in the entrypoint.
* This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.
* The excess is left as a deposit in the entrypoint, for future calls.
* can be withdrawn anytime using "entryPoint.withdrawTo()"
* In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.
*/
function validateUserOp(UserOperation calldata userOp, bytes32 requestId, uint256 requiredPrefund) external;
function validateUserOp(UserOperation calldata userOp, bytes32 requestId, uint256 missingWalletFunds) external;
}
6 changes: 3 additions & 3 deletions contracts/samples/DepositPaymaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ contract DepositPaymaster is BasePaymaster {
token.safeTransfer(target, amount);
}

function getTokenToEthOutputPrice(IERC20 token, uint256 ethBought) internal view virtual returns (uint256 requiredTokens) {
function getTokenValueOfEth(IERC20 token, uint256 ethBought) internal view virtual returns (uint256 requiredTokens) {
IOracle oracle = oracles[token];
require(oracle != nullOracle, "DepositPaymaster: unsupported token");
return oracle.getTokenToEthOutputPrice(ethBought);
return oracle.getTokenValueOfEth(ethBought);
}

function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 requestId, uint256 maxCost)
Expand All @@ -115,7 +115,7 @@ contract DepositPaymaster is BasePaymaster {
require(userOp.paymasterData.length == 32, "DepositPaymaster: paymasterData must specify token");
IERC20 token = abi.decode(userOp.paymasterData, (IERC20));
address account = userOp.getSender();
uint256 maxTokenCost = getTokenToEthOutputPrice(token, maxCost);
uint256 maxTokenCost = getTokenValueOfEth(token, maxCost);
require(unlockBlock[account] == 0, "DepositPaymaster: deposit not locked");
require(balances[token][account] >= maxTokenCost, "DepositPaymaster: deposit too low");
return abi.encode(account, token, maxTokenCost, maxCost);
Expand Down
2 changes: 1 addition & 1 deletion contracts/samples/IOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ interface IOracle {
/**
* return amount of tokens that are required to receive that much eth.
*/
function getTokenToEthOutputPrice(uint256 ethOutput) external view returns (uint256 tokenInput);
function getTokenValueOfEth(uint256 ethOutput) external view returns (uint256 tokenInput);
}

8 changes: 4 additions & 4 deletions contracts/samples/SimpleWallet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ contract SimpleWallet is IWallet {
require(msg.sender == address(entryPoint), "wallet: not from EntryPoint");
}

function validateUserOp(UserOperation calldata userOp, bytes32 requestId, uint256 requiredPrefund) external override {
function validateUserOp(UserOperation calldata userOp, bytes32 requestId, uint256 missingWalletFunds) external override {
_requireFromEntryPoint();
_validateSignature(userOp, requestId);
_validateAndIncrementNonce(userOp);
_payPrefund(requiredPrefund);
_payPrefund(missingWalletFunds);
}

function _payPrefund(uint256 requiredPrefund) internal {
Expand Down Expand Up @@ -98,8 +98,8 @@ contract SimpleWallet is IWallet {
require(owner == hash.recover(userOp.signature), "wallet: wrong signature");
}

function _call(address sender, uint256 value, bytes memory data) internal {
(bool success, bytes memory result) = sender.call{value : value}(data);
function _call(address target, uint256 value, bytes memory data) internal {
(bool success, bytes memory result) = target.call{value : value}(data);
if (!success) {
assembly {
revert(add(result,32), mload(result))
Expand Down
8 changes: 4 additions & 4 deletions contracts/samples/TokenPaymaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import "../BasePaymaster.sol";
* A sample paymaster that define itself as a token to pay for gas.
* The paymaster IS the token to use, since a paymaster cannot use an external contract.
* Also, the exchange rate has to be fixed, since it can't reference an external Uniswap or other exchange contract.
* subclass should override "getTokenToEthOutputPrice to provide actual token exchange rate, settable by the owner.
* subclass should override "getTokenValueOfEth to provide actual token exchange rate, settable by the owner.
* Known Limitation: this paymaster is exploitable when put into a batch with multiple ops (of different wallets):
* - while a single op can't exploit the paymaster (if postOp fails to withdraw the tokens, the user's op is reverted,
* and then we know we can withdraw the tokens), multiple ops with different senders (all using this paymaster)
Expand Down Expand Up @@ -50,14 +50,14 @@ contract TokenPaymaster is BasePaymaster, ERC20 {

//TODO: this method assumes a fixed ratio of token-to-eth. subclass should override to supply oracle
// or a setter.
function getTokenToEthOutputPrice(uint256 valueEth) internal view virtual returns (uint256 valueToken) {
function getTokenValueOfEth(uint256 valueEth) internal view virtual returns (uint256 valueToken) {
return valueEth / 100;
}

// verify that the user has enough tokens.
function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 /*requestId*/, uint256 requiredPreFund)
external view override returns (bytes memory context) {
uint256 tokenPrefund = getTokenToEthOutputPrice(requiredPreFund);
uint256 tokenPrefund = getTokenValueOfEth(requiredPreFund);

// make sure that verificationGas is high enough to handle postOp
require(userOp.verificationGas > COST_OF_POST, "TokenPaymaster: gas too low for postOp");
Expand Down Expand Up @@ -94,7 +94,7 @@ contract TokenPaymaster is BasePaymaster, ERC20 {
//we don't really care about the mode, we just pay the gas with the user's tokens.
(mode);
address sender = abi.decode(context, (address));
uint256 charge = getTokenToEthOutputPrice(actualGasCost + COST_OF_POST);
uint256 charge = getTokenValueOfEth(actualGasCost + COST_OF_POST);
//actualGasCost is known to be no larger than the above requiredPreFund, so the transfer should succeed.
_transfer(sender, address(this), charge);
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/test/TestOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.12;
import "../samples/IOracle.sol";

contract TestOracle is IOracle {
function getTokenToEthOutputPrice(uint256 ethOutput) external pure override returns (uint256 tokenInput) {
function getTokenValueOfEth(uint256 ethOutput) external pure override returns (uint256 tokenInput) {
return ethOutput * 2;
}
}
2 changes: 1 addition & 1 deletion eip/EIPS/eip-4337.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The core interface required for a wallet to have is:

```c++
function validateUserOp
(UserOperation calldata userOp, bytes32 requestId, uint requiredPrefund)
(UserOperation calldata userOp, bytes32 requestId, uint missingWalletFunds)
external;
```

Expand Down
6 changes: 3 additions & 3 deletions reports/gas-used-output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
·······················|······················|············|··············|·············|···············|··············
| EntryPoint · addStake · 29068 · 46168 · 34768 · 3 · - │
·······················|······················|············|··············|·············|···············|··············
| EntryPoint · handleOps · 98035 · 1185457 · 425966 · 27 · - │
| EntryPoint · handleOps · 98035 · 1185485 · 425964 · 27 · - │
·······················|······················|············|··············|·············|···············|··············
| EntryPoint · simulateValidation · - · - · 999715 · 1 · - │
| EntryPoint · simulateValidation · - · - · 999703 · 1 · - │
·······················|······················|············|··············|·············|···············|··············
| EntryPoint · unstakeDeposit · - · - · 28381 · 1 · - │
·······················|······················|············|··············|·············|···············|··············
Expand All @@ -41,7 +41,7 @@
··············································|············|··············|·············|···············|··············
| DepositPaymaster · - · - · 1333412 · 4.4 % · - │
··············································|············|··············|·············|···············|··············
| TokenPaymaster · - · - · 1581382 · 5.3 % · - │
| TokenPaymaster · - · - · 1581358 · 5.3 % · - │
··············································|············|··············|·············|···············|··············
| VerifyingPaymaster · - · - · 1016722 · 3.4 % · - │
·---------------------------------------------|------------|--------------|-------------|---------------|-------------·