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

bug: serialize & writeJson are not deterministic #4592

Closed
2 tasks done
OliverNChalk opened this issue Mar 18, 2023 · 2 comments · Fixed by #4599
Closed
2 tasks done

bug: serialize & writeJson are not deterministic #4592

OliverNChalk opened this issue Mar 18, 2023 · 2 comments · Fixed by #4599
Labels
T-bug Type: bug

Comments

@OliverNChalk
Copy link
Contributor

Component

Forge

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (06f7c9c 2023-03-18T00:08:48.50351195Z)

What command(s) is the bug in?

No response

Operating System

Linux

Describe the bug

I would expect that writeJson and related cheatcodes would produce a deterministic result. However, across runs this output will be different:

This code:

    function _deployerMetadata() private returns (string memory rDeployerMetadata) {
        string memory lObjectKey = "qwerty";

        vm.serializeBytes32(lObjectKey, "factory_hash", keccak256(type(GenericFactory).creationCode));
        vm.serializeBytes32(lObjectKey, "constant_product_hash", keccak256(type(ConstantProductPair).creationCode));
        vm.serializeBytes32(lObjectKey, "stable_hash", keccak256(type(StablePair).creationCode));
        rDeployerMetadata = vm.serializeBytes32(lObjectKey, "oracle_caller_hash", keccak256(type(OracleCaller).creationCode));
    }

    // SNIP

    vm.writeJson(
        _deployerMetadata(),
        "scripts/unoptimized-deployer-meta"
    );

Produces:

{
  "oracle_caller_hash": "0x262458524d9c8928fe7fd7661236b93f6d6a9535182f48fd582a75f18bfbf85f",
  "constant_product_hash": "0x043551969376243d49aff4ce627e029219c6d90e16c780a7d2ef4f72b6fcf236",
  "factory_hash": "0x67de66ba417a88060e4b7b0cde0d56b01973a4b9f0066385ba661c58d2d6ca50",
  "stable_hash": "0x3239f5ad44712803a6036e7a99f6fdfb9f98f22d8e39ebff8de3c1996ab5dfec"
}

OR:

{
  "oracle_caller_hash": "0x262458524d9c8928fe7fd7661236b93f6d6a9535182f48fd582a75f18bfbf85f",
  "constant_product_hash": "0x043551969376243d49aff4ce627e029219c6d90e16c780a7d2ef4f72b6fcf236",
  "stable_hash": "0x3239f5ad44712803a6036e7a99f6fdfb9f98f22d8e39ebff8de3c1996ab5dfec",
  "factory_hash": "0x67de66ba417a88060e4b7b0cde0d56b01973a4b9f0066385ba661c58d2d6ca50"
}

And so forth. I imagine it should be possible to serialize the keys in alphabetical order, though not sure if this will need to be custom implemented or can be easily done with serde_json::Value

@sakulstra
Copy link
Contributor

sakulstra commented Apr 11, 2023

Hey, i'm still facing this issue on latest nightly - probably i'm doing sth slightly different though as i'm working with nested objects.

When i do sth like:

function repro() internal {
    string memory content;

    for (uint256 i = 0; i < 2; i++) {
        string memory key = vm.toString(i);
        vm.serializeUint(key, 'a', 100);
        string memory object = vm.serializeUint(key, 'b', 200);
        content = vm.serializeString(eModesKey, key, object);
      }
    }
    string memory output = vm.serializeString('root', 'category', content);
    vm.writeJson(output, path);
  }

The output will alternate between:

{
  category: {
    0: {a: 100, b: 200},
    1: {a: 100, b: 200}
  }
}

and

{
  category: {
    1: {a: 100, b: 200},
    0: {a: 100, b: 200}
  }
}

https://github.com/bgd-labs/aave-helpers/blob/master/src/ProtocolV3TestBase.sol#L255-L283

@mds1
Copy link
Collaborator

mds1 commented Apr 11, 2023

cc @odyslam, added this to #3801 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-bug Type: bug
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants