Skip to content
This repository has been archived by the owner on Nov 5, 2023. It is now read-only.

Audit fixes 1-4 and BLSWalletWrapper changes #350

Merged
merged 20 commits into from
Oct 27, 2022

Conversation

jzaki
Copy link
Collaborator

@jzaki jzaki commented Oct 4, 2022

What is this PR doing?

Fixes audit points 1-4, and the latest commit has updates to BLSWalletWrapper to handle changing addresses referred to by a key.

How can these changes be manually tested?

yarn hardhat test inside contracts

Does this PR resolve or contribute to any issues?

Related to PR #340
closes #287

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)

@jzaki jzaki requested a review from jacque006 October 4, 2022 21:23
@github-actions github-actions bot added clients contracts Smart contract related labels Oct 4, 2022
// eslint-disable-next-line camelcase
VerificationGateway__factory,
} from "../typechain";
} from "../../typechain";
Copy link
Collaborator

@voltrevo voltrevo Oct 5, 2022

Choose a reason for hiding this comment

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

This is reaching out to contracts/typechain which is incorrect. contracts/clients needs to be self-contained so that it can be published on npm. contracts/clients/typechain in the repo is a symlink to contracts/typechain. (Replacing the symlink dir with the actual content occurs during build.)

Copy link
Collaborator

@jacque006 jacque006 Oct 5, 2022

Choose a reason for hiding this comment

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

Addressed in #351

const walletContract = BLSWallet__factory.connect(
contractAddress,
provider,
await blsWalletWrapper.syncWallet(verificationGateway);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the syncWallet here is redundant since the latest address information is gathered above during await BlsWalletWrapper.BLSWallet(privateKey, verificationGateway)?

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is currently only being used in the should recover before bls key update contracts test when recovering to a different key, so this still may be needed during the recovery workflow to keep non-async properties of BlsWalletWrapper up to date with their on-chain values.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Confirmed, removing that syncWallet call fails the test Error: VM Exception while processing transaction: reverted with reason string 'VG: Sig not verified'

@@ -25,6 +25,8 @@ export default (domain: Uint8Array, chainId: number) =>
BigNumber.from(n2).toHexString(),
BigNumber.from(n3).toHexString(),
]),
bundle.operations.map(encodeMessageForSigning(chainId)),
bundle.operations.map((op, i) =>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nitpick: Unused variable i

Copy link
Collaborator

@jacque006 jacque006 Oct 5, 2022

Choose a reason for hiding this comment

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

Removed

for (uint256 i=0; i<32; i++) {
if (i<4) {
selectorId |= bytes4(encodedFunction[i]) >> i*8;
}
Copy link
Collaborator

@voltrevo voltrevo Oct 5, 2022

Choose a reason for hiding this comment

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

Are you sure this is the correct shift direction? Usually you'd shift left in this situation (to move a byte into the more significant location, since <<, >> follows big endian convention, even on modern architectures that are usually little endian).

I can see how it might be inverted for bytes4... curious.

It might be better to use uint32 for the arithmetic and then cast to bytes4 after?

Comment on lines 155 to 164
bundleFrom(
async bundleFrom(
wallet: BlsWalletWrapper,
contract: Contract,
method: string,
params: any[],
nonce: BigNumberish,
ethValue: BigNumberish = 0,
): Bundle {
): Promise<Bundle> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unnecessary async conversion here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Addressed

@@ -187,7 +189,14 @@ export default class Fixture {
) {
await (
await this.verificationGateway.processBundle(
this.bundleFrom(wallet, contract, method, params, nonce, ethValue),
await this.bundleFrom(
Copy link
Collaborator

Choose a reason for hiding this comment

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

After fixing bundleFrom, you shouldn't need await here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Addressed

@@ -201,7 +210,7 @@ export default class Fixture {
ethValue: BigNumberish = 0,
) {
return await this.verificationGateway.callStatic.processBundle(
this.bundleFrom(wallet, contract, method, params, nonce, ethValue),
await this.bundleFrom(wallet, contract, method, params, nonce, ethValue),
Copy link
Collaborator

Choose a reason for hiding this comment

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

As above.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Addressed

Copy link
Collaborator

@voltrevo voltrevo left a comment

Choose a reason for hiding this comment

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

A few things, mostly minor.

@voltrevo
Copy link
Collaborator

voltrevo commented Oct 5, 2022

How can these changes be manually tested?

yarn hardhat test inside contracts

I don't see any new tests covering the critical changes that have been made:

  1. A bundle signed for a different address cannot be replayed onto a wallet with the same bls key
  2. VG disallows calling transferOwnership and renounceOwnership

Not that we're strict about always automating these things, but they should be manually tested. Have you manually tested them? (In particular, my question about the shift direction could be resolved by a manual test.)

@jzaki jzaki changed the base branch from main to contract-updates October 5, 2022 16:28
@github-actions github-actions bot added the automation CI/CD related label Oct 5, 2022
@jacque006
Copy link
Collaborator

Two ways I can see us finishing this up:

  1. Merge as is into contract-updates, open a PR from that to main and address remaining comment(s) and client integrations in contract-updates branch/PR.
  2. Change the target of this PR to main and address remaining comment(s) & client integrations here.

I am fine with either.

Update aggregator BundleService to work with new signature payload which includes wallet address.
@github-actions github-actions bot added aggregator Aggregator backend related aggregator-proxy Aggregator proxy related extension Browser extension related labels Oct 5, 2022
@@ -1,6 +1,6 @@
{
"name": "bls-wallet-clients",
"version": "0.7.3",
"version": "0.8.0",
Copy link
Collaborator

@jacque006 jacque006 Oct 5, 2022

Choose a reason for hiding this comment

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

@voltrevo Given contract changes, especially signed payload format w/ wallet address I bumped the minor to indicate a breaking change.

@jacque006
Copy link
Collaborator

jacque006 commented Oct 5, 2022

Remaining Tasks

  • @jzaki additional updates to contracts & tests. TODO Was this done?

Manual Testing

  • Regression test extension, which should also test aggregator. Will do in PR to main

Automated testing (contracts)

  • Add test case(s) for A bundle signed for a different address cannot be replayed onto a wallet with the same bls key
  • Add test case(s) for VG disallows calling transferOwnership & renounceOwnership
  • Add test case for VG: first param to proxy admin is not calling wallet

Post Merge Will do in PR to main

  • Tag new repo release (assuming all audit issues are addressed)
  • Publish and pin in repo bls-wallet-clients@0.8.0
  • Deploy contract updates to Goerli Arbitrum
  • Update other projects/repos?

@blakecduncan
Copy link
Contributor

Two ways I can see us finishing this up:

  1. Merge as is into contract-updates, open a PR from that to main and address remaining comment(s) and client integrations in contract-updates branch/PR.
  2. Change the target of this PR to main and address remaining comment(s) & client integrations here.

I am fine with either.

@jacque006 Was there a decision made on how to move forward with this PR? Asking because I'll need the BLSWalletWrapper changes in order to get wallet recovery working end to end. Also, if there's anywhere I can help out with this let me know. I'm happy to jump in anywhere if I can.

@jacque006
Copy link
Collaborator

@blakecduncan Yes, it was decided to merge into contract-updates, and from there then merge into main after more through regression testing/other changes.

If you need the wrapper changes now, you can use bls-wallet-clients@0.8.0-2d28b7b

Would love your help testing the extension when we move to testing before main

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Oct 24, 2022
@@ -248,4 +285,52 @@ describe("Recovery", async function () {
.recoverWallet(addressSignature, hashAttacker, salt, wallet1Key),
).to.be.rejectedWith("VG: Signature not verified for wallet address");
});

it("should NOT allow a bundle to be executed on a wallet with the same BLS pubkey but different address (replay attack)", async function () {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe this covers A bundle signed for a different address cannot be replayed onto a wallet with the same bls key test case that was needed, but it is difficult to tell as this key switch via recovery will de-register the first wallet with that pubkey.

Add getOperationResults to bls-wallet-clients to allow consumers to more easily get at operation errors.
Change existing test case to use getOperationResults.
Add message to require used to prevent ownership changes to proxy admin.
@jacque006 jacque006 mentioned this pull request Oct 26, 2022
@jacque006
Copy link
Collaborator

#366 will be pulled in to replace latest commit after merge to main

@jacque006 jacque006 merged commit 93c7935 into contract-updates Oct 27, 2022
@jacque006 jacque006 deleted the contract-audit branch October 27, 2022 15:54
@jacque006
Copy link
Collaborator

After discussion with @jzaki , decided to merge early to contract-updates. Will continue testing additions & client integration there.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
aggregator Aggregator backend related aggregator-proxy Aggregator proxy related automation CI/CD related clients contracts Smart contract related documentation Improvements or additions to documentation extension Browser extension related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants