35 Commits

Author SHA1 Message Date
Dror Tirosh
fc171eb64a AA 92 simulate execution (#152)
1. A new API for an account (or paymaster) to report signature check validation: instead of revert, they should return `SIG_VALIDATION_FAILED` (1) to mark signature validation.  checking for `tx.origin` as zero is no longer in use.
2. ValidateUserOp returns the SIG_VALIDATION_FAILED value (like any other deadline) for a bundler to check.
3. `handleOps`  reverts on such signature failure.
4. a new `simulateHandleOp()` helper method, which executes a full UserOp (validation+execution).
   like `validateUserOp`, it reverts so it never commits changes on-chain, and doesn't check for signatures, and only used for off-chain simulation. This way, a userOp can be "estimated", even if it depends on the deployed account (e.g. it is a method call on a newly deployed account, or depends on the account's state such as its balance)
2022-12-26 16:09:40 +02:00
Dror Tirosh
976d3f2758 AA-91 factories (#151)
* fix factories

BLSFactory use same model as SimpleAccount, using immutable wallet and
only user-specific params in initializer
add factory for TestAggregatedAccount sapmle contract
Create2Factory - use arachnid's de-facto standard deployer, instead of of
the nonstandard EIP2470 (specifically, arachnid's deployer revert on errors)

* gnosis account factory
now Gnosis-Safe  based account uses only standard gnosis contracts. The new GnosisSafeAcccountFactory only wraps the standard GnosisSafeProxyFactory to create the proxy (and initialize it with our modules)
2022-12-20 20:35:08 +02:00
Alex Forshtat
35b16cdd21 AA-74: sample account cleanup: using ERC1967Proxy instead of instance (#149)
AA-74: sample account cleanup part 1 - using ERC1967Proxy instead of instance

* Remove the 'updateEntryPoint' API as it is not needed - the
'setImplementation' flow should take care of this.

* Make EntryPoint an immutable member of the SimpleAccount implementation

* Merge 'exec' and 'execFromEntryPoint' into single 'execute' method

* Remove '_requireFromAdmin' and 'transfer' functions

* use factory in getAccountInitCode/getAccountAddress, not implementation and ERC1967Proxy

Co-authored-by: Dror Tirosh <dror@opengsn.org>
2022-12-16 13:41:27 +02:00
Dror Tirosh
57c5d77c77 AA 73 unify reputation (#144)
* reputation (and stake) mechanism to apply to all entities (factory, paymaster, aggregator and account)
* event change: actualGasUsed instead of actualGasPrice
* all entities (sender, factory, paymaster, aggregator) return stake info from simulateValidation
* use "Factory" instead of "deployer"
* emit SignatureAggregatorChanged, AccountDeployed to help bundler with reputation calculation.

Co-authored-by: Yoav Weiss <yoavw@users.noreply.github.com>
2022-12-14 16:59:06 +02:00
Dror Tirosh
93cd881dca AA-68 rpc calls (#132)
* Add rpc methods definitions

better definition of the required RPC methods:

* eth_sendUserOperation
* eth_estimateUserOperationGas
* eth_getUserOperationReceipt
* eth_supportedEntryPoints

* fixed error codes, error examples, removed "mined"
2022-12-13 12:16:24 +02:00
Dror Tirosh
695e490484 AA-61 rename wallet to account (#134)
* rename IWallet to IAccount (and all other contracts, e.g. SimpleWallet to SimpleAccount, etc..)
2022-11-27 17:22:37 +02:00
Dror Tirosh
11cb5aaac3 AA-67 relax storage rules in opcode banning (#121)
allow a wallet to access wallet-specific storage in other contracts (based on its own address)
2022-11-16 03:38:30 +02:00
Dror Tirosh
4c0b1eeff4 AA-63 remove paymaster stake value from EntryPoint (#119)
- stake-value and unstake delay are not managed by entryPoint.
- `simulateValidation()` does return them (in its `SimulationResult`, so that the bundler can validate the paymaster stake is valid (and reject the UserOp if not)
- stake values for a signature aggregator are also returned (in SimulationResultWithAggregation`, ) if the wallet uses an aggregator.
2022-11-16 01:07:31 +02:00
Dror Tirosh
403f682854 AA-51: simpler simulation api, including aggregation
- simulateValidation() always reverts - successful result is error `SimulationResult`
- (no need to call from address(0), but always need to catch revert reason)
- returns also aggregator address, and never calls it.
- bundler should either reject UserOP or validate the signature using `aggregator.validateUserOpSignature()` (or an equivalent native library code)
2022-11-15 16:54:07 +02:00
Dror Tirosh
d45442739a AA-48 extract interfaces (#109)
extract IEntryPoint, IStakeManager
all core interfaces in "interfaces"
all core contracts in "core"
2022-08-24 01:48:30 +03:00
Dror Tirosh
6fbc3cf006 AA-36: Support deterministic mutli-chain addresses (#100)
initCode as deployer+data, instead of constructor code
- supports any deployer contract
- initCode doesn't have to include entire CREATE2 constructor code (it is only a method call to the deployer contract)
2022-08-23 21:09:48 +03:00
Dror Tirosh
0cddeaa720 AA-22: Support aggregated signatures and BLS ref. implementation (#92)
* update the EIP to support aggregated signatures

* support creation of aggregated wallet (simulateValidation)

* simulateValidation with param offChainSigCheck

if false, calls aggregator.validateUserOpSignature
if true, returns also offChainSigInfo to be used by off-chain code to
validate the signature

* hash pubkey into requestId

Vitalik Buterin [01/08/2022 10:40]:
Basically, if one account has a pubkey P, someone can make an evil
account with key Q - P, where they know q (the privkey of Q), and then
they pass off a signature with q as being an "aggregate" signature of
the same message signed by both K1 = P and K2 = Q-P (because K1 + K2 =
Q)

The fix to this is to hash the pubkey into the msghash, so you never get
two different keys signing the same message.
And I think this has to be enforced at the BLS aggregate verifier layer

Co-authored-by: Alex Forshtat <forshtat1@gmail.com>
2022-08-21 15:19:20 +02:00
Dror Tirosh
925528be5a AA-29: gnosis proxy (#96)
* inital code

import Gnosis code as-is.
probably can remove all non-essential contracts (e.g. test, samples)
or better, import as external library.

* removed unused contracts (not used,fail compilation)

* initial Gnosis-Safe Proxy account

* refactor:

- use @gnosis.pm/safe-contracts package
- separate contracts into separate files.

* cleanup, single owner

* cleanup contracts

simpler fallback handler

* added tests

failure cases
counterfactual creation

* change to "Manager"

- manager is not a module, only fallback, entrypoint
- replaceManager now works

* ignore from coverage

(fails to compile for coverage)

* fix dangling test

* Fix lint

* Set expected code lenght to be 324

Co-authored-by: Alex Forshtat <forshtat1@gmail.com>
2022-07-27 18:40:57 +02:00
Dror Tirosh
e74604e3b7 AA-21: gas usage tests for different batch scenarios (#93)
use with "yarn gas-checker"
currently deploys batches of 1,2,20,21, and display the gas diff
2022-07-24 11:27:36 +03:00
Alex Forshtat
f5fed715b8 AA-30: Add eslint task to the repository (#97)
Co-authored-by: Dror Tirosh <dror@opengsn.org>
2022-07-07 23:23:20 +03:00
Dror Tirosh
720390fcd5 [N11] IWallet doesn't strongly enforce required functionality (#82)
introduce BaseWallet, which provides basic wallet functionality to subclasses.
2022-03-31 13:22:48 +03:00
Dror Tirosh
ed175c5ea6 [M02] Separate stake and prepayment (#76)
* [M02] Separate stake and prepayment

seperate "stake" from deposit
- keep separate stake and deposit balances.
- stake is unmodified. paymaster only pays from its deposit.
- paymaster pre-pay for the request, just like the wallet does (and refunded at the end)
2022-03-30 14:03:12 +03:00
Dror Tirosh
69e48a0488 Wallet should not used "banned" opcodes (#35)
* ban GAS opcode in validateUserOp
* SimpleWallet without using "gas"
  created a version of ECDSA library that doesn't use the "gas" opcode
  (calling the ecrecover precompile using assembly)
  also avoid using "gas" opcode while sending prefund to EntryPoint
2022-01-24 21:41:48 +02:00
Dror Tirosh
e5cb0cdd8b add eth-gas-reporter to "yarn ci" build (#29)
* add eth-gas-reporter to "yarn ci" build
* `createWalletOwner()` (and `createAddress()`) now generate deterministic addresses, so they don't skew gas calculations (zero-bytes in calldata fluctuate gas usage)
2022-01-18 19:34:08 +02:00
Dror Tirosh
be744f4b65 add "requestId" to event (#23)
* add "requestId" to event
  requestID is a unique identifier of current request. it is a hash of the entire UserOperation content (except the signature) with chainid and entrypoint address.

* cleanup obsolete methods (simulateWalletValidation, simulatePaymasterValidation) - should use "simulateValidation", which combines them together.

* updated runop
2022-01-05 03:11:31 +02:00
Dror Tirosh
b1fe37766d Use wallet deposit (#21)
- simplified stake/deposit mechanism
- send eth to EntryPoint adds to deposit
- remove "walletEth" mode: always pay from wallet deposit.
- user is not automatically refunded after the call (deposit is left for future calls) - can use "withdrawTo" call to retrieve its leftover deposit.

- add chainId to hash before signature.
- refactor:
   name methods as per the EIP (verifyUserOp=>validateUserOp)
   redeemer => beneficiary
   redeem() => compensate
2022-01-01 13:06:41 +02:00
Dror Tirosh
a899fcc246 Time based unstake delay (#20)
* use timestamp for stake
  instead of blocks, count stake in seconds (block.timestamp)
2021-12-23 09:57:12 +02:00
Dror Tirosh
a6843e154f basefee legacy test (#18)
validate that in legacy mode (maxPriorityFee==maxBaseFee) we indeed
don't execute the 'BASEFEE'
2021-12-12 13:33:04 +02:00
Dror Tirosh
4464c8b9d7 single simulateValidate call (#17)
A single "static" call method that performs both wallet.validateUserOp
and paymaster.validatePaymasterUserOp.

In order to do opcode-tracing separately on those methods, the caller
should look for the SELFBALANCE at depth=1
there is exactly one such call before and another after the
`validateUserOp`, so the opcodes between (at depth>=2) are the
validateUserOp code.
The opcode validation of `verifyPaymasterUserOp` is for the code after
the 2nd SELFBALANCE
2021-11-17 14:17:03 +02:00
Dror Tirosh
660465e15c use EIP2470 singleton creator. (#14)
* use EIP2470 singleton creator.
* deployEntryPoint(), to deploy entry point using create2
2021-10-06 02:49:46 +03:00
Dror Tirosh
e17ab102a7 rename fields (#11)
* rename fields

Singleton=>EntryPoint
target=>sender
payForSelfOp => validateUserOp
payForOp => validatePaymasterUserOp
added preVerificationGas

removed execFromSingleton from interface (it is required by actual
implementation, but actual signature is wallet-specific)
2021-09-29 15:59:28 +03:00
Dror Tirosh
2b34defea8 added stakemanager tests (#10) 2021-09-25 19:08:32 +03:00
Dror Tirosh
a03088419a Gas overhead, Ban opcodes (#9)
* added perOpOverhead

* added batch tests , large batches for testing construction, large TXs, heavy cpu.

* test for banned opcodes in simulateWalletVerification

* removed banning of GAS opcode in payForSelf testing.

* add github test workflow
2021-09-23 16:33:46 +03:00
Dror Tirosh
afd36ef5a5 refactors, more tests (#8)
added batch test (multiple TXs)
fixed tests to properly use execFromSingleton
- some gas optimizations (handling of calldata, modified signature
encoding)
- some refactors to wrap assembly code (_call, _create2)
- calcGasUsage- compare rcpt.gasUsed to paid userop
2021-08-30 11:44:59 +03:00
Dror Tirosh
bc54947f37 remove "signer" field. (#7)
No explicit "signer" field.
wallet may define a signer, depending on its signature scheme.
wallet constructor MUST have signer as parameter, to make target address
unqiue.
2021-08-30 11:43:30 +03:00
Dror Tirosh
49ef41da6e postOp gets dynamic context (#6)
* postOp gets dynamic context

postOp gets "bytes calldata context" instead of "bytes32" AND UserOperation.

rationale: in most cases, the entire UserOperation is not required by postOp, or at most, a single field is required.
OTOH, for complex paymasters, there might be some calculations in the payForOp that ARE required in the "postOp"

with the dynamic context, the paymaster decides exactly what to pass to its postOp, whether copy of field(s) form the UserOp, or locally calculated data.
If none is needed, it can be left empty.

- normal userOp cost ~400 more
- "create" operation cost 5000 less

* fixed test, initial geth testing support
2021-08-26 10:29:59 +03:00
Dror Tirosh
b2864d0016 various gas calculations
- add verificationGas, verificationAccessListHash
- use `block.basefee` (solidity 0.8.7)
-
2021-08-16 16:11:08 +03:00
Dror Tirosh
e02c24a7a5 support create2 using initCode
userOp: added initCode - constructor code to run.

executed before payForOp (obviously..)
callData is the initialization code.

TokenPaymaster expects initCode to approve getting tokens (that's why it
has to "whitelist" both constructor code and init function.
2021-08-16 11:49:07 +03:00
Dror Tirosh
2f3c6d0240 singleton tests 2021-08-09 00:15:43 +03:00
Dror Tirosh
cc25fd62e0 initial tests 2021-08-06 19:25:01 +03:00