diff --git a/.gas-snapshot b/.gas-snapshot index e1b2448a..ee202d87 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,10 +1,10 @@ -LibDescribedByMetaEmitForDescribedAddressTest:testEmitForDescribedAddressHappy(bytes) (runs: 5099, μ: 262353, ~: 262297) -LibDescribedByMetaEmitForDescribedAddressTest:testEmitForDescribedAddressMismatch(bytes,bytes) (runs: 5099, μ: 264255, ~: 264233) -LibMetaCheckMetaHashedV1_2Test:testCheckMetaHashedV1_2BadMagicBadHash(bytes,bytes32) (runs: 5099, μ: 5634, ~: 5616) -LibMetaCheckMetaHashedV1_2Test:testCheckMetaHashedV1_2BadMagicGoodHash(bytes) (runs: 5099, μ: 5719, ~: 5694) -LibMetaCheckMetaHashedV1_2Test:testCheckMetaHashedV1_2GoodMagicBadHash(bytes,bytes32) (runs: 5099, μ: 5783, ~: 5771) -LibMetaCheckMetaHashedV1_2Test:testCheckMetaHashedV1_2Happy(bytes) (runs: 5099, μ: 1103, ~: 1095) -LibMetaCheckMetaUnhashedV1_2Test:testCheckMetaUnhashedV1_2Fuzz(bytes) (runs: 5099, μ: 5818, ~: 5797) -LibMetaIsRainMetaV1_2Test:testIsRainMetaV1_2Fuzz(bytes) (runs: 5099, μ: 4167, ~: 4162) -MetaBoardHashTest:testMetaboardHash(bytes) (runs: 5099, μ: 199676, ~: 199660) -MetaBoardTest:testEmitMeta(bytes32,bytes) (runs: 5099, μ: 207801, ~: 207693) \ No newline at end of file +LibDescribedByMetaEmitForDescribedAddressTest:testEmitForDescribedAddressHappy(bytes) (runs: 5096, μ: 267020, ~: 266892) +LibDescribedByMetaEmitForDescribedAddressTest:testEmitForDescribedAddressMismatch(bytes,bytes) (runs: 5093, μ: 269394, ~: 269260) +LibMetaCheckMetaHashedV1_2Test:testCheckMetaHashedV1_2BadMagicBadHash(bytes,bytes32) (runs: 5096, μ: 6031, ~: 5974) +LibMetaCheckMetaHashedV1_2Test:testCheckMetaHashedV1_2BadMagicGoodHash(bytes) (runs: 5096, μ: 6515, ~: 6334) +LibMetaCheckMetaHashedV1_2Test:testCheckMetaHashedV1_2GoodMagicBadHash(bytes,bytes32) (runs: 5096, μ: 6383, ~: 6321) +LibMetaCheckMetaHashedV1_2Test:testCheckMetaHashedV1_2Happy(bytes) (runs: 5096, μ: 1275, ~: 1228) +LibMetaCheckMetaUnhashedV1_2Test:testCheckMetaUnhashedV1_2Fuzz(bytes) (runs: 5096, μ: 6780, ~: 6564) +LibMetaIsRainMetaV1_2Test:testIsRainMetaV1_2Fuzz(bytes) (runs: 5096, μ: 1197, ~: 1153) +MetaBoardHashTest:testMetaboardHash(bytes) (runs: 5096, μ: 200262, ~: 200200) +MetaBoardTest:testEmitMeta(bytes32,bytes) (runs: 5096, μ: 212497, ~: 212154) \ No newline at end of file diff --git a/flake.lock b/flake.lock index 09614c3d..894a168e 100644 --- a/flake.lock +++ b/flake.lock @@ -75,11 +75,11 @@ "nixpkgs": "nixpkgs" }, "locked": { - "lastModified": 1741023058, - "narHash": "sha256-LSd/8CBlpDLjci5ANFJjP0w+dGdY/mqKsyUfhjGwnfs=", + "lastModified": 1758705030, + "narHash": "sha256-zYM8PiEXANNrtjfyGUc7w37/D/kCynp0cQS+wCQ77GI=", "owner": "shazow", "repo": "foundry.nix", - "rev": "66becfe20b7e688b8f2e5774609c4436cf202ba0", + "rev": "b59a55014050110170023e3e1c277c1d4a2f055b", "type": "github" }, "original": { @@ -104,11 +104,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1747828570, - "narHash": "sha256-tv8R4Z/69GC8zogsb5TNDRj5tkhMeHpyYIzRl1cJigo=", + "lastModified": 1758711836, + "narHash": "sha256-uBqPg7wNX2v6YUdTswH7wWU8wqb60cFZx0tHaWTGF30=", "owner": "nixos", "repo": "nixpkgs", - "rev": "040a62f13f40879a05578a66dd4ae0d284c55a5b", + "rev": "46f97b78e825ae762c0224e3983c47687436a498", "type": "github" }, "original": { @@ -135,11 +135,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1731531548, - "narHash": "sha256-sz8/v17enkYmfpgeeuyzniGJU0QQBfmAjlemAUYhfy8=", + "lastModified": 1748662220, + "narHash": "sha256-7gGa49iB9nCnFk4h/g9zwjlQAyjtpgcFkODjcOQS0Es=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "24f0d4acd634792badd6470134c387a3b039dace", + "rev": "59138c7667b7970d205d6a05a8bfa2d78caa3643", "type": "github" }, "original": { @@ -158,11 +158,11 @@ "solc": "solc" }, "locked": { - "lastModified": 1748346550, - "narHash": "sha256-Rlaj/hHHACo0blFKane6/arqIXWUCGe/sCNgqX8VfZ8=", + "lastModified": 1760460761, + "narHash": "sha256-IHvwnmphDaOyZnzvObwOoDQlA9nzym2ZUxe9K/5vs0U=", "owner": "rainprotocol", "repo": "rainix", - "rev": "a1a5c321f356cb5006d16dd2d1a2242c183b7e96", + "rev": "add0d8a1fd76ce0e65b962c952e9252257876465", "type": "github" }, "original": { @@ -182,11 +182,11 @@ "nixpkgs": "nixpkgs_3" }, "locked": { - "lastModified": 1747795013, - "narHash": "sha256-c7i0xJ+xFhgjO9SWHYu5dF/7lq63RPDvwKAdjc6VCE4=", + "lastModified": 1758681214, + "narHash": "sha256-8cW731vev6kfr58cILO2ZsjHwaPhm88dQ8Q6nTSjP9I=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "6b1cf12374361859242a562e1933a7930649131a", + "rev": "b12ed88d8d33d4f3cbc842bf29fad93bb1437299", "type": "github" }, "original": { @@ -202,11 +202,11 @@ "solc-macos-amd64-list-json": "solc-macos-amd64-list-json" }, "locked": { - "lastModified": 1742758229, - "narHash": "sha256-FrU9rhab/0vOjjeFoQF+Ej43zRLv3enUIYjgLrH3Gd8=", + "lastModified": 1756368702, + "narHash": "sha256-cqEHv7uCV0LibmQphyiXZ1+jYtGjMNb9Pae4tfcAcF8=", "owner": "hellwolf", "repo": "solc.nix", - "rev": "6885b61bac89da19a6e3c70b89fdd592e2cef884", + "rev": "d83e90df2fa8359a690f6baabf76099432193c3f", "type": "github" }, "original": { @@ -218,13 +218,13 @@ "solc-macos-amd64-list-json": { "flake": false, "locked": { - "narHash": "sha256-U5ckttxwKO13gIKggel6iybG5oTDbSidPR5nH3Gs+kY=", + "narHash": "sha256-AvITkfpNYgCypXuLJyqco0li+unVw39BAfdOZvd/SPE=", "type": "file", - "url": "https://github.com/ethereum/solc-bin/raw/30a3695/macosx-amd64/list.json" + "url": "https://github.com/argotorg/solc-bin/raw/26fc3fd/macosx-amd64/list.json" }, "original": { "type": "file", - "url": "https://github.com/ethereum/solc-bin/raw/30a3695/macosx-amd64/list.json" + "url": "https://github.com/argotorg/solc-bin/raw/26fc3fd/macosx-amd64/list.json" } }, "systems": { diff --git a/foundry.lock b/foundry.lock new file mode 100644 index 00000000..2fa9b50a --- /dev/null +++ b/foundry.lock @@ -0,0 +1,5 @@ +{ + "lib/forge-std": { + "rev": "b8f065fda83b8cd94a6b2fec8fcd911dc3b444fd" + } +} \ No newline at end of file diff --git a/lib/forge-std b/lib/forge-std index f46d8301..b8f065fd 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit f46d8301cf732f4f83846565aa475628265e51e0 +Subproject commit b8f065fda83b8cd94a6b2fec8fcd911dc3b444fd diff --git a/src/concrete/MetaBoard.sol b/src/concrete/MetaBoard.sol index 57ee8a37..e88f2733 100644 --- a/src/concrete/MetaBoard.sol +++ b/src/concrete/MetaBoard.sol @@ -16,6 +16,12 @@ contract MetaBoard is IMetaBoardV1_2 { /// under its hash. This avoids the need to roll a new interface to include /// hashes in the event logs. function hash(bytes calldata data) external pure returns (bytes32) { - return keccak256(data); + bytes32 dataHash; + assembly ("memory-safe") { + let free := mload(0x40) + calldatacopy(free, data.offset, data.length) + dataHash := keccak256(free, data.length) + } + return dataHash; } } diff --git a/src/interface/unstable/IMetaV1_2.sol b/src/interface/unstable/IMetaV1_2.sol index 559972f4..dbca2d27 100644 --- a/src/interface/unstable/IMetaV1_2.sol +++ b/src/interface/unstable/IMetaV1_2.sol @@ -2,6 +2,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd pragma solidity ^0.8.19; +//forge-lint: disable-next-line(unused-import) import {UnexpectedMetaHash, NotRainMetaV1, META_MAGIC_NUMBER_V1} from "../deprecated/IMetaV1.sol"; /// @title IMetaV1_2 diff --git a/src/lib/LibDescribedByMeta.sol b/src/lib/LibDescribedByMeta.sol index ee31236e..db9db16c 100644 --- a/src/lib/LibDescribedByMeta.sol +++ b/src/lib/LibDescribedByMeta.sol @@ -13,7 +13,10 @@ library LibDescribedByMeta { internal { bytes32 expected = described.describedByMetaV1(); - bytes32 actual = keccak256(meta); + bytes32 actual; + assembly ("memory-safe") { + actual := keccak256(add(meta, 0x20), mload(meta)) + } if (actual != expected) { revert MetadataMismatch(described, expected, actual); } diff --git a/src/lib/LibMeta.sol b/src/lib/LibMeta.sol index b19f5ca6..aa1d4feb 100644 --- a/src/lib/LibMeta.sol +++ b/src/lib/LibMeta.sol @@ -2,6 +2,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd pragma solidity ^0.8.19; +//forge-lint: disable-next-line(unused-import) import {IMetaV1_2, UnexpectedMetaHash, NotRainMetaV1, META_MAGIC_NUMBER_V1} from "../interface/unstable/IMetaV1_2.sol"; /// @title LibMeta @@ -36,7 +37,10 @@ library LibMeta { /// `isRainMetaV1` OR it does not match the expected hash of its data. /// @param meta The metadata to check. function checkMetaHashedV1(bytes32 expectedHash, bytes memory meta) internal pure { - bytes32 actualHash = keccak256(meta); + bytes32 actualHash; + assembly ("memory-safe") { + actualHash := keccak256(add(meta, 0x20), mload(meta)) + } if (expectedHash != actualHash) { revert UnexpectedMetaHash(expectedHash, actualHash); } diff --git a/test/lib/LibDescribedByMeta.emitForDescribedAddress.t.sol b/test/lib/LibDescribedByMeta.emitForDescribedAddress.t.sol index b3957b09..57f4c79c 100644 --- a/test/lib/LibDescribedByMeta.emitForDescribedAddress.t.sol +++ b/test/lib/LibDescribedByMeta.emitForDescribedAddress.t.sol @@ -10,14 +10,14 @@ import {MetaBoard} from "src/concrete/MetaBoard.sol"; import {META_MAGIC_NUMBER_V1} from "src/interface/unstable/IMetaV1_2.sol"; contract TestDescribedByMetaV1 is IDescribedByMetaV1 { - bytes32 public immutable expected; + bytes32 public immutable EXPECTED; constructor(bytes memory meta) { - expected = keccak256(meta); + EXPECTED = keccak256(meta); } function describedByMetaV1() external view override returns (bytes32) { - return expected; + return EXPECTED; } } diff --git a/test/lib/LibMeta.checkMetaUnhashedV1_2.t.sol b/test/lib/LibMeta.checkMetaUnhashedV1_2.t.sol index c5d5b93a..3158576c 100644 --- a/test/lib/LibMeta.checkMetaUnhashedV1_2.t.sol +++ b/test/lib/LibMeta.checkMetaUnhashedV1_2.t.sol @@ -4,7 +4,7 @@ pragma solidity =0.8.25; import {Test} from "forge-std/Test.sol"; import {LibMeta} from "src/lib/LibMeta.sol"; -import {UnexpectedMetaHash, NotRainMetaV1, META_MAGIC_NUMBER_V1} from "src/interface/unstable/IMetaV1_2.sol"; +import {NotRainMetaV1, META_MAGIC_NUMBER_V1} from "src/interface/unstable/IMetaV1_2.sol"; contract LibMetaCheckMetaUnhashedV1_2Test is Test { function checkMetaUnhashedV1External(bytes memory meta) external pure { diff --git a/test/lib/LibMeta.isRainMetaV1_2.t.sol b/test/lib/LibMeta.isRainMetaV1_2.t.sol index a760679c..cbcbd516 100644 --- a/test/lib/LibMeta.isRainMetaV1_2.t.sol +++ b/test/lib/LibMeta.isRainMetaV1_2.t.sol @@ -4,7 +4,7 @@ pragma solidity =0.8.25; import {Test} from "forge-std/Test.sol"; import {LibMeta} from "src/lib/LibMeta.sol"; -import {UnexpectedMetaHash, NotRainMetaV1, META_MAGIC_NUMBER_V1} from "src/interface/unstable/IMetaV1_2.sol"; +import {META_MAGIC_NUMBER_V1} from "src/interface/unstable/IMetaV1_2.sol"; contract LibMetaIsRainMetaV1_2Test is Test { /// All data with the magic number prefix will be considered to be rain meta