-
Notifications
You must be signed in to change notification settings - Fork 306
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
Pay fees natively during account contract initialization #5190
Comments
Today account contracts are initialized by calling into their initializer method directly, meaning they don't go through a traditional Add fee payment to initializer. Along with the initialization arguments for the account contract (eg the authorization ECDSA public key), we can supply a Add a canonical initializer contract. This contract does not need to be enshrined, but it should be well-known. This contract should provide a common entrypoint that takes care of initialization and fee payment in the account contract. The logic should be something along the lines of:
Note that this approach, while a lot cleaner since it does not need the dangerous |
Personally, I'm leaning towards the second option as it seems cleaner and safer. The One problem I see is that the fee is designed to go at the beginning of the execution, marking itself as 'non-revertibe'. If we follow the "init, then pay the fee" flow then the initialisation becomes part of the non-revertible part of a tx. This becomes a problem if an account contract in the future requires public initialisation as that would be tagged for the setup phase, meaning it either has to be whitelisted by the sequencer or the sequencer takes on risk that init would take significant compute and eventually revert. Ideally we'd setup the fee first inside I'll come back here once I have a solution |
I'm afraid that if you go down this route you end up in a situation where you need a method in the account contract to validate a fee payload before initialization, which means you manually need to reconstruct the init args from the address preimage, which means you end up implementing something very similar to the first option. I'd suggest restricting account contracts to only have private constructors if they are meant to be deployed this way. And if it needs a public constructor, then have it initialized from another account who pays the fee. |
Coming back with an update after thinking through this a bit more and chatting with @spalladino on slack. We propose two flows. Account contract initialiserThis would be a new protocol contract that would be responsible for initialising individual account contracts. Like in the comment above:
The Pros:
Cons:
The initialiser would run as part of the private setup phase meaning whatever nullifiers/notes it emits become part of the non-revertible set. I don't immediately see an issue with this, a fee still gets paid for the data. SecurityA malicious user could craft an account contract that enqueues public functions to be executed as part of the public setup phase. In this case the sequencer protects itself by whitelisting which contract instances/classes are allowed to run in setup and would reject the unrecongised account contract. Pop capsuleWe can take Palla's initial suggestion, but instead of adding the macro
Pros:
Cons:
SecuritySame security implications apply. If a malicious account contract tries to inject code into public setup, it would get rejected by the sequencer through the fact that it's not on the approved fee payment contracts. PS: I'm starting to think that maybe the naming we chose for revertible/non-revertible side effects might not have been the best. If an action in either phase reverts then the tx "fails" but in one case it soft-reverts and goes on chain and pays a partial fee while in the other it hard-reverts and is rejected by the sequencer. |
Thanks for the writeup! Just one more comment from me:
I don't think this is a security issue inherent of this task. Anyone can deploy a contract that behaves like this, regardless of what we do with account initialization. |
After a bit of back and forth on capsules we've agreed to go the account contract initialiser route with one difference. Instead of deploying a new protocol contract whose sole responsibility is to intialise account contracts, we instead are using the canonical multi call entrypoint to do it. The multi call contract will receive a payload with the following function calls:
In order to achieve this we have modified the entrypoint interface to accept transient authwits alongside function calls so that the yet-to-be-deployed-account can create an authwit authorizing the fee payload. |
This PR enables accounts to pay tx fees when they're deployed. To achieve this a new deployment method was added that's used by the `AccountManager` class to optionally register/publicly deploy and initialize the target account contract. Entrypoint classes now accept authwits/packed arguments alongside the normal function calls from before. This is needed so that authwits could be created in a parent context and then passed along as transient authwits to the transaction (see `ExecutionRequestInit` wrapper type) Initializing an account contract can use any of the three existing payment methods: - using bridged gas token from L1 - paying privately through a fee payment contract - paying publicly through a fee payment contract In order to use fee payment contracts this PR adds `noinitcheck` to `spend_private_authwit` and `spend_public_authwit` because it's not possible to read the init nullifier in the current tx (protocol limitation). Instead the contract relies on the note containing the public key to exist to validate that the contract has been initialized correctly. An extra payment flow is tested as well: a third party takes the account's public keys and deploys and initializes the account while paying the associated fee. This simulates the flow where a deployment service is used that takes payment through a side chain (e.g. fiat). Breaking change: moved `DefaultMultiCallEntrypoint` to aztec.js This PR supersedes #5540 and #5543. Fix #5190 #5191 #5544.
No description provided.
The text was updated successfully, but these errors were encountered: