8000 Use safe singleton factory by voltrevo · Pull Request #464 · getwax/bls-wallet · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
This repository was archived by the owner on Nov 5, 2023. It is now read-only.

Use safe singleton factory #464

Merged
merged 29 commits into from
Mar 2, 2023

Conversation

voltrevo
Copy link
Collaborator
@voltrevo voltrevo commented Jan 18, 2023

What is this PR doing?

Ports our deployment to use safe's singleton factory.

This has the massive advantage of making the addresses of our deployments predetermined for all networks and for any tx.origin used to do the deployment.

In making the switch, I've also fixed the deterministic generation of VerificationGateway's ProxyAdmin using the new ProxyAdminGenerator. This was critical to getting a predetermined address for VerificationGateway because proxyAdmin was a constructor parameter, which affects VerificationGateway's address. This was a pre-existing issue: #332.

Removes:

  • create2Deployer
  • DEPLOYER_* variables
  • contracts/scripts/0_deploy_precompile_cost_estimator.ts
  • contracts/scripts/1_deploy_bls_wallet_contracts.ts
  • contracts/scripts/deploy-deployer.ts
  • create2Fixture (replaced by SafeSingletonFactory class)
  • lazyBlsWallets (replaced by fx.createBLSWallet()) (was always a bit clunky, and was the cause of test failures)

There's also a workaround called fx.processBundleWithExtraGas. The automatic gasLimit isn't sufficient for setPendingBLSKeyForWallet, I think this has to do with the call depth involved... ie, the gasLimit is enough for the actual amount of gas used, but not enough gas is provided to one of the deeply nested calls since 63/64ths of the gas is provided to each next layer.

Finally, I've added getCostEstimator() to BLS.sol as a temporary workaround while we wait for Safe's singleton factory on 1337: safe-global/safe-singleton-factory#97. This function just selects the right cost estimator based on the chain id, which means that testing using geth doesn't require editing this file.

How can these changes be manually tested?

  • yarn hardhat test
  • Check the scripts in scripts/test

Does this PR resolve or contribute to any issues?

Resolves #394, #332, #334.

Checklist

  • I have manually tested these changes
  • Post a link to the PR in the group chat

Guidelines

  • If your PR is not ready, mark it as a draft
  • The resolve conversation button is for reviewers, not authors
    • (But add a 'done' comment or similar)

@github-actions github-actions bot added clients contracts Smart contract related labels Jan 18, 2023
@voltrevo voltrevo force-pushed the bw-394-use-safe-singleton-factory branch from b85ab59 to f877f94 Compare January 18, 2023 23:42
@voltrevo voltrevo changed the base branch from main to contract-updates January 18, 2023 23:42
@voltrevo voltrevo force-pushed the bw-394-use-safe-singleton-factory branch from ca71aec to 97bf29c Compare January 18, 2023 23:50
@github-actions github-actions bot added the automation CI/CD related label Jan 18, 2023
@voltrevo voltrevo force-pushed the bw-394-use-safe-singleton-factory branch from 31884bc to ec94ac9 Compare January 19, 2023 02:27
@voltrevo voltrevo force-pushed the bw-394-use-safe-singleton-factory branch from ec94ac9 to 73967ce Compare January 19, 2023 02:43
@voltrevo voltrevo force-pushed the bw-394-use-safe-singleton-factory branch from ace4a32 to ae7886a Compare January 23, 2023 05:47
@voltrevo voltrevo marked this pull request as ready for review January 23, 2023 05:51
@voltrevo voltrevo requested a review from jzaki January 23, 2023 05:58
id := chainid()
}

if (id == 1337) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need chainid 31337 for hardhat support?

Copy link
Collaborator Author
@voltrevo voltrevo Feb 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do, but it's not needed here because safe has provided the signed transaction we need for 31337, so the cost estimator address is at the same location across networks.

Comment on lines 45 to 68
/**
* This is a temporary workaround while we wait for Safe's singleton factory
* deployment signature for chain id 1337:
* https://github.com/safe-global/safe-singleton-factory/issues/97
*
* In the meantime, this allows us to do fast testing using geth dev mode,
* just without getting the same address in this test environment.
*
* This adds:
* - 1824 L1 gas ($0.05) to the deployment of BLSOpen (114 bytes)
* - 71 L2 gas ($0.000012) to signature verification
*/
function getCostEstimator() internal pure returns (address) {
uint256 id;
assembly {
id := chainid()
}

if (id == 1337) {
return COST_ESTIMATOR_ADDRESS_1337;
}

return COST_ESTIMATOR_ADDRESS;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than modifying this file, I think it would be safer to just have a script/process that updates the COST_ESTIMATOR_ADDRESS before contract deploy.

Some risks with this approach:

  • There is no guarantee that another EVM network would not use chainid 1337. See this article for an example of when this happened with an existing chainid with ETHPoW after The Merge
  • Although I have never seen it happen, chainid is not guaranteed to be the same block to block. A chain could choose at some point to change its chainid. OpenZepplin accounts for this in their EIP-712 implementation
  • As an attacker, if I could get a chain/network to switch its chainid to 1337 for a short time & I deployed a malicious contract to COST_ESTIMATOR_ADDRESS_1337 I could generate my own precompileGasCost and do Bad Things with BLS sig verification. This seems unlikely on most larger/established networks, but I could see it happening on a smaller EVM network/L2, especially if its security/consensus mechanisms are more centralized.

I also could see passing the cost estimator address as an arg to verifySingle/multiple, but that is a more significant change. IMO, asides from updating the COST_ESTIMATOR_ADDRESS, we should not update/change the BLS libs/contracts taken from Hubble.

Related: #189

Copy link
Collaborator Author
@voltrevo voltrevo Feb 10, 2023 •< 10000 /span>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hear you, but I think you are overlooking two things:

  1. The 1337 address is still hardcoded to an address which can only contain the same logic, due to the deterministic deployment. Messing with the chainid does not allow an attacker to insert a malicious cost estimator.
  2. This is not intended to ever deploy to a non-test network.

I wouldn't be happy with modifying the file when using 1337 deployments, because I think that leads to a lot of subtle confusion, as we experienced previously when the committed address here was correct for production but not development.

If you have any contacts at safe, it would be really nice if they just provided the signature we need. It should really only take a few minutes of their time and avoid all this mess.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jacque006 Moot now, Safe came through and I deleted all this code 🎉.

@@ -22,6 +22,9 @@
"dependencies": {
"@openzeppelin/contracts": "^4.7.3"
},
"peerDependencies": {
"ethers": "^5.0.0"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was this needed for?

Copy link
Collaborator Author
@voltrevo voltrevo Feb 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes lint issue.

Related: #511 (comment)

Comment on lines +111 to +122
await (
await signer.sendTransaction({
to: deployment.signerAddress,
value: ethers.BigNumber.from(deployment.gasPrice).mul(
deployment.gasLimit,
),
})
).wait();

await (
await signer.provider.sendTransaction(deployment.transaction)
).wait();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👎 Nested awaits (others spots with this, will only comment here :) )

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conversation here: #511 (comment)

Comment on lines 21 to 28
export type Deployment = {
singletonFactory: SafeSingletonFactory;
precompileCostEstimator: BNPairingPrecompileCostEstimator;
blsLibrary: BLSOpen;
verificationGateway: VerificationGateway;
blsExpander: BLSExpander;
aggregatorUtilities: AggregatorUtilities;
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to consolidate this type with BlsWalletContracts in clients

@jacque006
Copy link
Collaborator

@jzaki should also review & determine final approval

Co-authored-by: Jacob Caban-Tomski <jacque006@users.noreply.github.com>
@voltrevo voltrevo force-pushed the bw-394-use-safe-singleton-factory branch from 8fe7706 to e416c13 Compare February 13, 2023 05:57
Copy link
Collaborator
@jzaki jzaki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from the PA point, the rest I'm fine with going into v1. V2 will have a clearer plan from the beginning.

@@ -61,11 +65,11 @@ contract VerificationGateway
constructor(
IBLS bls,
address blsWalletImpl,
address proxyAdmin
ProxyAdminGenerator proxyAdminGenerator
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously the PA and VG deployment were in the same function, and when needing to deploy our own deployer, this was deterministic. With the change to using the safe singleton factory, the smaller change (preserving audit as much as possible) would have been to change PA in place to be deployed with the safe singleton factory.
Also the design of a separate PA Generator although cleaner in some ways, implies use of PAs more generally in this application which I'd rather lean away from.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticed this was changed in the following commits (#536 ) ✔️

* enough in our testing environment. This method works around that by adding
* 50% to the gas estimate.
*/
async processBundleWithExtraGas(bundle: Bundle, overrides: Overrides = {}) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contract tests were working without this, so is this regarding aggregator tests?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The smart contract tests have changed from a simple call line to multiple lines breaking things up to sign, adding many more lines to the test functions and making them much less clear.
Since this is seems to be a typescript preference, I'm willing to concede this for v1, but we can work together on more integrated use of client code in v2 contract tests.

* Chosen arbitrarily
* =keccak256(abi.encodePacked(uint32(0xfeedbee5)))
*/
bytes32 BLS_DOMAIN = 0x0054159611832e24cdd64c6a133e71d373c5f8553dde6c762e6bffe707ad83cc;
Copy link
Collaborator
@jzaki jzaki Mar 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still the arbitrarily generated hash? Arguably this takes more bytes than the opcodes, but VG size is not as important as wallet size. So just curious about the change. Just noticed comment in #527

@voltrevo voltrevo merged commit 25c73d6 into contract-updates Mar 2, 2023
@voltrevo voltrevo deleted the bw-394-use-safe-singleton-factory branch March 2, 2023 09:10
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
1C6A
Labels
automation CI/CD related clients contracts Smart contract related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update contract deployment to use safe singleton factory
3 participants
0