diff --git a/src/Gatekeeper.sol b/src/Gatekeeper.sol index c14bfa3..50ea531 100644 --- a/src/Gatekeeper.sol +++ b/src/Gatekeeper.sol @@ -10,6 +10,7 @@ import {StorageHistory} from "./types/StorageHistory.sol"; import {Weaver} from "./types/Weaver.sol"; import {FullMath} from "./libraries/FullMath.sol"; +import {Verifier} from "./libraries/Verifier.sol"; import {Checkpoints} from "./libraries/Checkpoints.sol"; import {RotationPacking, RequestPacking, GovernancePacking} from "./libraries/Packing.sol"; import {ReentrancyGuard} from "@openzeppelin-contracts/utils/ReentrancyGuard.sol"; @@ -22,7 +23,7 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard { uint256 private constant BOUNTY_DIVISOR = type(uint32).max; uint256 private constant SECP256K1_N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; - uint256 private constant SECP256K1_Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141; + uint256 private constant SECP256K1_Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F; uint256 private constant SHIFT_FACTOR = (2**128) % SECP256K1_N; uint256 public constant GAS_RECALL_SPENDING = 329188; @@ -113,12 +114,14 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard { function verify( bytes calldata call, - bytes calldata nonce, - bytes32 s - ) external nonReentrant payable returns (bytes memory) { - _verifySchnorrSignature(call, nonce, s); + uint256 rx, + uint256 s + ) external nonReentrant returns (bytes memory) { + uint256 px = _extractPublicKey(call); + bool validSignature = Verifier.verifyGhost(call, px, rx, s); + if (!validSignature) revert BadSignature(); - (bool success, bytes memory data) = address(this).call{ value: msg.value }(call); + (bool success, bytes memory data) = address(this).call(call); if (!success) revert ExecutionReverted(); return data; @@ -138,7 +141,7 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard { uint256 exodusSession, uint256 amount, uint256 packed - ) external override payable { + ) external override { if (msg.sender != address(this)) revert NotGatekeeper(); RequestPacking.RequestPayload memory payload = RequestPacking.unpack(packed); @@ -173,8 +176,9 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard { uint8 newParity ) external override { if (msg.sender != address(this)) revert NotGatekeeper(); - StorageHistory(storageHistory).trySetTransactionExecuted(exodusSession); + if (newParity % 2 != 0) revert InvalidPublicKey(); + StorageHistory(storageHistory).trySetTransactionExecuted(exodusSession); // forge-lint: disable-next-line(unsafe-typecast) uint256 packedRotationState = RotationPacking.pack(newParity, uint64(exodusSession)); @@ -202,85 +206,15 @@ contract Gatekeeper is IGatekeeper, Weaver, ReentrancyGuard { return data; } - function _verifySchnorrSignature(bytes calldata call, bytes calldata nonce, bytes32 s) internal view { - (bytes32 px, uint8 p) = _extractPublicKey(call); - - uint8 v = p == 0 ? 27 : 28; - bytes32 e = _challenge(call, nonce, px, p); - - bytes32 sp = bytes32(SECP256K1_Q - mulmod(uint256(s), uint256(px), SECP256K1_Q)); - bytes32 ep = bytes32(SECP256K1_Q - mulmod(uint256(e), uint256(px), SECP256K1_Q)); - address recoveredR = ecrecover(sp, v, px, ep); - - if (sp == 0) revert BadSignature(); - if (recoveredR == address(0)) revert BadSignature(); - if (recoveredR != _uncompressedPointToAddress(nonce)) revert BadSignature(); - } - - function _uncompressedPointToAddress(bytes calldata nonce) internal pure returns (address) { - if (nonce.length != 65) revert BadSignature(); - if (nonce[0] != 0x04) revert BadSignature(); - - bytes32 rx = bytes32(nonce[1:33]); - bytes32 ry = bytes32(nonce[33:65]); - - return address(uint160(uint256(keccak256(abi.encodePacked(rx, ry))))); - } - - function _extractPublicKey(bytes calldata call) internal view returns (bytes32, uint8) { + function _extractPublicKey(bytes calldata call) internal view returns (uint256) { if (call.length < 36) revert InvalidCalldata(); uint256 exodusSession; assembly { exodusSession := calldataload(add(call.offset, 4)) } - (bytes32 publicKey, uint8 parity,) = getRotationInfoAt(exodusSession); + (bytes32 publicKey,,) = getRotationInfoAt(exodusSession); - return (publicKey, parity); - } - - function _challenge( - bytes calldata call, - bytes calldata r, - bytes32 pk, - uint8 v - ) internal pure returns (bytes32) { - if (r.length != 65) revert BadSignature(); - - bytes32 rx = bytes32(r[1:33]); - bytes1 rv; - - { - bytes32 ry = bytes32(r[33:65]); - uint8 rParityByte = (uint256(ry) & 1) == 0 ? 0x02 : 0x03; - rv = bytes1(rParityByte); - } - - uint8 pv = v == 0 ? 0x02 : 0x03; - - bytes memory message = abi.encodePacked(rv, rx, pv, pk, call); - bytes memory domain = "FROST-secp256k1-SHA256-v1chal"; - uint8 dstlen = uint8(domain.length); - - bytes32 b0 = sha256(abi.encodePacked( - bytes32(0), - bytes32(0), - message, - hex"0030", - uint8(0), - domain, - dstlen - )); - - bytes32 b1 = sha256(abi.encodePacked(b0, uint8(1), domain, dstlen)); - bytes32 b2 = sha256(abi.encodePacked(b0 ^ b1, uint8(2), domain, dstlen)); - - uint256 high32 = uint256(b1); - uint256 lowPart = uint256(b2) >> 128; - - uint256 highReduced = mulmod(high32, SHIFT_FACTOR, SECP256K1_N); - uint256 finalChallenge = addmod(highReduced, lowPart, SECP256K1_N); - - return bytes32(finalChallenge); + return uint256(publicKey); } } diff --git a/src/interfaces/IGatekeeper.sol b/src/interfaces/IGatekeeper.sol index 1472c46..ee7000a 100644 --- a/src/interfaces/IGatekeeper.sol +++ b/src/interfaces/IGatekeeper.sol @@ -9,6 +9,7 @@ interface IGatekeeper { error NotGatekeeper(); error AlreadyExecuted(); error InvalidCalldata(); + error InvalidPublicKey(); error NonExistentAmount(); error InsufficientValue(); error ExecutionReverted(); @@ -25,7 +26,7 @@ interface IGatekeeper { function getRotationInfoAt(uint256 session) external view returns (bytes32, uint8, uint64); function govern(uint256 session, uint256 payload, bytes calldata call) external returns (bytes calldata); - function recall(uint256 session, uint256 amount, uint256 payload) external payable; + function recall(uint256 session, uint256 amount, uint256 payload) external; function rotate(uint256 session, bytes32 publicKey, uint8 parity) external; function ghost(bytes32 receiver, uint256 amount) external returns (uint256); function initialize(address previousAddress) external; diff --git a/src/libraries/Hashes.sol b/src/libraries/Hashes.sol index 807eaef..051c1ec 100644 --- a/src/libraries/Hashes.sol +++ b/src/libraries/Hashes.sol @@ -17,12 +17,30 @@ library Hashes { } } - function efficientKeccak256(bytes32 a, bytes32 b, bytes32 c) internal pure returns (bytes32 value) { + function efficientKeccak256(uint256 a, uint256 b) internal pure returns (bytes32 value) { assembly ("memory-safe") { mstore(0x00, a) mstore(0x20, b) - mstore(0x40, c) - value := keccak256(0x00, 0x60) + value := keccak256(0x00, 0x40) + } + } + + function efficientKeccak256Prefixed(bytes32 a) internal pure returns (bytes32 value) { + assembly ("memory-safe") { + let ptr := mload(0x40) + mstore8(ptr, 0x00) + mstore(add(ptr, 0x01), a) + value := keccak256(ptr, 0x21) + } + } + + function efficientKeccak256Prefixed(bytes32 a, bytes32 b) internal pure returns (bytes32 value) { + assembly ("memory-safe") { + let ptr := mload(0x40) + mstore8(ptr, 0x01) + mstore(add(ptr, 0x01), a) + mstore(add(ptr, 0x21), b) + value := keccak256(ptr, 0x41) } } } diff --git a/src/mocks/WeaverMock.sol b/src/mocks/WeaverMock.sol index 0dc435a..1583706 100644 --- a/src/mocks/WeaverMock.sol +++ b/src/mocks/WeaverMock.sol @@ -7,7 +7,6 @@ contract WeaverMock is Weaver { address private _previousAddress; constructor(address previousWeaver) { - Weaver._initialize(previousWeaver); _previousAddress = previousWeaver; } diff --git a/src/types/Weaver.sol b/src/types/Weaver.sol index 6b6c377..333436b 100644 --- a/src/types/Weaver.sol +++ b/src/types/Weaver.sol @@ -61,10 +61,10 @@ abstract contract Weaver is IWeaver { bytes32 left = bytes32(_treeNodes[session][j].upperLookup(atBlock)); bytes32 right = bytes32(_treeNodes[session][j | 1].upperLookup(atBlock)); - bytes32 leftHash = Hashes.efficientKeccak256(left); - bytes32 rightHash = Hashes.efficientKeccak256(right); + bytes32 leftHash = Hashes.efficientKeccak256Prefixed(left); + bytes32 rightHash = Hashes.efficientKeccak256Prefixed(right); - currentLevel[i] = Hashes.efficientKeccak256(leftHash, rightHash); + currentLevel[i] = Hashes.efficientKeccak256Prefixed(leftHash, rightHash); unchecked { ++i; } } @@ -73,10 +73,10 @@ abstract contract Weaver is IWeaver { i = 0; for (; i < currentLevelCount;) { uint256 j = i << 1; - bytes32 left = currentLevel[j]; - bytes32 right = currentLevel[j | 1]; + bytes32 leftHash = currentLevel[j]; + bytes32 rightHash = currentLevel[j | 1]; - currentLevel[i] = Hashes.efficientKeccak256(left, right); + currentLevel[i] = Hashes.efficientKeccak256Prefixed(leftHash, rightHash); unchecked { ++i; } } } @@ -106,7 +106,7 @@ abstract contract Weaver is IWeaver { for (; i < currentLevelCount;) { bytes32 leaf = bytes32(_treeNodes[session][i].upperLookup(atBlock)); - currentLevel[i] = Hashes.efficientKeccak256(leaf); + currentLevel[i] = Hashes.efficientKeccak256Prefixed(leaf); unchecked { ++i; } } @@ -123,7 +123,7 @@ abstract contract Weaver is IWeaver { bytes32 left = currentLevel[j]; bytes32 right = currentLevel[j | 1]; - currentLevel[i] = Hashes.efficientKeccak256(left, right); + currentLevel[i] = Hashes.efficientKeccak256Prefixed(left, right); unchecked { ++i; } } diff --git a/test/gatekeeper/Gatekeeper.t.sol b/test/gatekeeper/Gatekeeper.t.sol index 81fa0c3..882a169 100644 --- a/test/gatekeeper/Gatekeeper.t.sol +++ b/test/gatekeeper/Gatekeeper.t.sol @@ -4,6 +4,7 @@ import {Test} from "forge-std/Test.sol"; import {Gatekeeper} from "../../src/Gatekeeper.sol"; import {FullMath} from "../../src/libraries/FullMath.sol"; +import {Verifier} from "../../src/libraries/Verifier.sol"; import {RequestPacking} from "../../src/libraries/Packing.sol"; import {IStorageHistory} from "../../src/interfaces/IStorageHistory.sol"; import {StorageHistory} from "../../src/types/StorageHistory.sol"; @@ -159,13 +160,9 @@ contract MockStaking is Test { uint256 amount, uint256 packed, address caller - ) external payable { - if (msg.value > 0) { - vm.deal(address(gatekeeper), address(gatekeeper).balance + msg.value); - } - + ) external { vm.prank(address(gatekeeper), caller); - gatekeeper.recall{value: msg.value}(exodusSession, amount, packed); + gatekeeper.recall(exodusSession, amount, packed); } function recall(address receiver, uint256 amount) external { @@ -273,10 +270,22 @@ contract GatekeeperTest is Test { assert(IStorageHistory(storageHistory).isTransactionExecuted(exodusSession)); } - function test_rotateWork(bytes32 aggregatedPublicKey) public { + function test_rotateWork() public { vm.warp(block.timestamp + 1); vm.prank(address(gatekeeper)); - gatekeeper.rotate(block.timestamp, aggregatedPublicKey, 0); + gatekeeper.rotate(block.timestamp, 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0); + + vm.warp(block.timestamp + 1); + vm.prank(address(gatekeeper)); + gatekeeper.rotate(block.timestamp, 0xF9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9, 0); + + vm.warp(block.timestamp + 1); + vm.prank(address(gatekeeper)); + gatekeeper.rotate(block.timestamp, 0x3590A94E768F8E1815C2F24B4D80A8E3149316C3518CE7B7AD338368D038CA66, 0); + + vm.warp(block.timestamp + 1); + vm.prank(address(gatekeeper)); + gatekeeper.rotate(block.timestamp, 0xD4E0D4642DB1613B2C94A81FCD34E39A2A31ACD774CD42525A88CF69EBA2E611, 0); } function test_couldNotBridgeBelowExistential(uint256 amount) public { @@ -297,16 +306,16 @@ contract GatekeeperTest is Test { staking.runGhost(bytes32(abi.encodePacked(ALICE)), type(uint104).max); vm.prank(ALICE); - gatekeeper.updatePublicKeyMetadata(0, 0x875cdcba4ae5494518fa2602791e667ca0998402b6a69e5b7cb4c72dba4e4669, 0); + gatekeeper.updatePublicKeyMetadata(0, 0x36ff5b7f0fc50100b563c6072e499980d6e6aa8528ea0ae6d776cf7e8e96c374, 0); (bytes32 prevPublicKey, uint8 prevParity,) = gatekeeper.latestPublicKeyInfo(); // genesis validators 4 validators, DKG #0 // exodus session #0 gatekeeper.verify( - hex"49f03a670000000000000000000000000000000000000000000000000000000000000000875cdcba4ae5494518fa2602791e667ca0998402b6a69e5b7cb4c72dba4e46690000000000000000000000000000000000000000000000000000000000000000", - hex"044d9fa18df9da04381ed256981570a6ef6a0893496ded966fc994662df931ed423b29e2737394b31d8498594caad7b77e36ab31ac79df3796a1b6f26baa5552ae", - 0x24029a571fcaeadd14f4afe8be62afe3d07876ae270c3caf446ecb6cfc7c08f2 + hex"49f03a67000000000000000000000000000000000000000000000000000000000000000036ff5b7f0fc50100b563c6072e499980d6e6aa8528ea0ae6d776cf7e8e96c3740000000000000000000000000000000000000000000000000000000000000000", + 0x58a4ef4e4f9cad19e9bb3707a48f01920ba309f69892609b196bbc112b6aebea, + 0x2de1a8116c65a290c51fee3bac24546c09522423640ae0e38f45791b1d81a069 ); (bytes32 publicKey, uint8 parity, uint64 session) = gatekeeper.latestPublicKeyInfo(); @@ -317,17 +326,17 @@ contract GatekeeperTest is Test { // could not apply signature from DKG #2 vm.expectRevert(); gatekeeper.verify( - hex"49f03a6700000000000000000000000000000000000000000000000000000000000000133492bc8bb10848f1f788496ccadde7d458eac4ac2c1eca2dd2c7a506d8fa2c5b0000000000000000000000000000000000000000000000000000000000000000", - hex"0434c3b37293516c6204dc291821e19ab5b3d8afb0947a0a2dffc91600fbd3f6b9783a66887d515e774b98a63a35a08bb3d914407fd768e92020b0ebaa3c8602b3", - 0x71cd57e697af70f84a960cc94fcbae5889efbf919df410282a04c6d19f92609e + hex"49f03a6700000000000000000000000000000000000000000000000000000000000000135353a4ce3430b37cabb7c495aabfec94895183672738873f4b227bf4ce31fbe50000000000000000000000000000000000000000000000000000000000000000", + 0xd1e4b50b4ff3e9b98ce17b375d6007cf0cf9d65e795cbe682609c1343361a81c, + 0x0cdd6c13658d862e7f816c59ad9cb1b6f5b3b981f019e698f27d1a354dc69cd5 ); // genesis validators 7 validators, DKG #1 // exodus session #11 gatekeeper.verify( - hex"49f03a67000000000000000000000000000000000000000000000000000000000000000b4e8c1fe96d6737cdabbcc96501d6656b9d0b659b3a528ef507f2d52bef29e1570000000000000000000000000000000000000000000000000000000000000000", - hex"04b51db09ec2f4bebdb65c5352efa75f8d07088408e3ff907c74b0d7928a40dbe06f864364a3e6d219849ca8e7d47e6c66f8a18ca9f4fa4752df13bb6c2eae1172", - 0x072e625bdd3ff7d09f2bf896b5e261efa007f8d81a9e2c828525ec74bd3ee08d + hex"49f03a67000000000000000000000000000000000000000000000000000000000000000bb5cd0d028a5e1b6a4eecb113b7e49c8176385eb77c8f134bc1db4bddd7654de60000000000000000000000000000000000000000000000000000000000000000", + 0x993fc0c870e1010f4933cbdb17b4539aea07234ff787eb3185d03ef8c0d2787e, + 0x4bfe369753a3125a37d13db08ea9125fe2280b70aa47e5890bf9401c785bdb92 ); (publicKey, parity, session) = gatekeeper.latestPublicKeyInfo(); @@ -341,9 +350,9 @@ contract GatekeeperTest is Test { // genesis validators 5 validators, DKG #2 // exodus session #19 gatekeeper.verify( - hex"49f03a6700000000000000000000000000000000000000000000000000000000000000133492bc8bb10848f1f788496ccadde7d458eac4ac2c1eca2dd2c7a506d8fa2c5b0000000000000000000000000000000000000000000000000000000000000000", - hex"0434c3b37293516c6204dc291821e19ab5b3d8afb0947a0a2dffc91600fbd3f6b9783a66887d515e774b98a63a35a08bb3d914407fd768e92020b0ebaa3c8602b3", - 0x71cd57e697af70f84a960cc94fcbae5889efbf919df410282a04c6d19f92609e + hex"49f03a6700000000000000000000000000000000000000000000000000000000000000135353a4ce3430b37cabb7c495aabfec94895183672738873f4b227bf4ce31fbe50000000000000000000000000000000000000000000000000000000000000000", + 0xd1e4b50b4ff3e9b98ce17b375d6007cf0cf9d65e795cbe682609c1343361a81c, + 0x0cdd6c13658d862e7f816c59ad9cb1b6f5b3b981f019e698f27d1a354dc69cd5 ); (publicKey, parity, session) = gatekeeper.latestPublicKeyInfo(); @@ -351,23 +360,22 @@ contract GatekeeperTest is Test { assertEq(parity, prevParity); assertEq(session, 19); - uint256 aliceAmountBefore = staking.recalledAmount(ALICE); uint256 bobAmountBefore = staking.recalledAmount(BOB); uint256 aliceBalanceBefore = ALICE.balance; uint256 bobBalanceBefore = BOB.balance; - // execute bridge out, happened on DKG #0 - // amount: 69; commission: 0%; ALICE + // execute bridge out, happened on DKG #1 + // amount: 34; commission: 0%; ALICE // exodus session #1 vm.prank(ALICE, ALICE); gatekeeper.verify( - hex"bf06188a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000010000000000007a6900000000", - hex"04bccb4cd4633e2c61ca5c65006a6a09baa893be219b21509866123a8d6299f92aefe9c380bd9728dbe0b93a8042f431636d08ed191b5c04062bf14e1347059cb9", - 0xe579753d931a78b143d7e3d86e1117ccbc9d2d7357b0207ea682046a0b06d798 + hex"bf06188a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000010000000000007a6900000000", + 0x74e1ee0256e3a1f6c38744fff8d72ffb905d660679e69c76b0af2e75db9fbfcc, + 0x4c512ab429d8c38a199daaa7f2c3d74956d2ff435871b160946b69804a1e5d54 ); - assertEq(aliceAmountBefore + 69, staking.recalledAmount(ALICE)); + assertEq(aliceAmountBefore + 34, staking.recalledAmount(ALICE)); assertEq(bobAmountBefore, staking.recalledAmount(BOB)); assertEq(aliceBalanceBefore, ALICE.balance); assertEq(bobBalanceBefore, BOB.balance); @@ -379,139 +387,138 @@ contract GatekeeperTest is Test { aliceBalanceBefore = ALICE.balance; bobBalanceBefore = BOB.balance; - uint256 buyback = 220; - - // execute bridge out, happened on DKG #1 - // amount: 420; commission: 50%; BOB + // TODO: revisit + // execute bridge out, happened on DKG #2 + // amount: 210; commission: 50%; BOB // exodus session #12 vm.prank(ALICE, ALICE); - gatekeeper.verify{value: buyback}( - hex"bf06188a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000020000000000007a6980000000", - hex"049f458500a78f56420380f0c6863905f1181e705f6b562eb469bd81a03676a2d9b436a53d2356ea0a5bb175ca837655fab8114c6e64cfdd47f3d36d1a945d7122", - 0x772731b359ee7ecac7830438333e4ffb61759b36610f69cef20f66f7a79a405f + gatekeeper.verify( + hex"bf06188a000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000020000000000007a6980000000", + 0x99c5f02bf312fc6b1a125b83397aa87df369738f85275bc42d249660abb1f0e1, + 0x8326ee3fc1cbb1421e2c974d6cc7cb2bfdc9c4f6ebfd403363f6b3a3bc8e9bef ); - assertApproxEqAbs(aliceAmountBefore + 210, staking.recalledAmount(ALICE), 1); - assertApproxEqAbs(bobAmountBefore + 210, staking.recalledAmount(BOB), 1); + assertApproxEqAbs(aliceAmountBefore + 105, staking.recalledAmount(ALICE), 1); + assertApproxEqAbs(bobAmountBefore + 105, staking.recalledAmount(BOB), 1); // execute setDistributor, exodusSession: 2 vm.prank(ALICE); gatekeeper.verify( hex"3137142600000000000000000000000000000000000000000000000000000000000000020000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002475619ab5000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000", - hex"049f222e7ec776c390c7fe96b9c2034c37f4fc71a9714588a5d98ccb50dc748c98fe375c628e7bcc4db4f204a2a168b22ecbc631616a69987ef42601ad239b2ab5", - 0x515539c5b713900a4dd4b3b119b22a47f862c90fdff9da91ed3fca687ea8db06 + 0x45a9889cb48e0eca44c3add96dc68d6ab728c1a7e4eab14323f0dcfe67472c1f, + 0x40e6980e96efc0fc6acf47aa0cd665bc5d85a01b909fc4d960948c76f45723b4 ); // execute setWarmupPeriod, exodusSession: 3 vm.prank(ALICE); gatekeeper.verify( hex"3137142600000000000000000000000000000000000000000000000000000000000000030000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024a85667c5000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000", - hex"04c2d9b903c0bd640ff858de3518c64965e2ff07215a131c85a8febec629999cfd60970a3a99d0d04ba08a334f2aa865842ebde37407c6fee2b17f820c8104fc88", - 0xe1727e132cbb7502a60bab56c5dedce1abca8130792ddd6d9ba59918766688e8 + 0x356ef46cfd654b0b609bdff33147df25c20ff9ca7ac3334c57f12e99b6248112, + 0xa6363286f97c02a39aa5280d74f8dc02dabd078911eef60e4848b7d5deeb325b ); // execute setBounty, exodusSession: 4 vm.prank(ALICE); gatekeeper.verify( hex"3137142600000000000000000000000000000000000000000000000000000000000000040000000000007a69010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000245d87d363000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000", - hex"04ec7d454696833a1c9c04d79be81e0dfe8a4791862f1dc5d4e908338df30621911fb182e6f204699c53ea5b11db1c855f55dfd149d4882a80afa437d80c58d9cd", - 0x22d3138ed4e72f104c5d86814c1b4e6eeed39cdcf97e087effe33f860d06f133 + 0xe6a419a5314afed1ff25df0cbf76f2002bfa9d7746817670f2487be5d7774118, + 0x7ce4c7207efdfdb9c71b26c7dd071572544fb27a329b348379d70b2e7a5f21fc ); // execute setAdjustment, exodusSession: 5 vm.prank(ALICE); gatekeeper.verify( hex"3137142600000000000000000000000000000000000000000000000000000000000000050000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000006446d36ab5000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000", - hex"0484819be6cb8879179f91aaf94c1513234d9068052dd42bf067606033c2d173efe85e87acf5bc1020cab6ec67d5ec8f7b237c5f315b825b56e915e4736c2b7b62", - 0x865b1e9006973e8b5b5492f2f6a0c85ee69ee7ae72f714ee076035865cd26a72 + 0x649a51e565d154f549e24aaf400ed9a2bb8812ed87eeac36372f36ac8cd6aa34, + 0xc9decb2fa41d9217f9a609d568f86bf92b66d6a91ed3c34031025d3845e34b09 ); // execute updateGatekeeperAddress, exodusSession: 6 vm.prank(ALICE); gatekeeper.verify( hex"3137142600000000000000000000000000000000000000000000000000000000000000060000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000002484f157cd000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000", - hex"040bfec065e85cb245d891a94b50b12ea8f91d27a90e113c0bf47f93e76c0c21380e6ff8dc05406d1e8ec34b2c90cc345fea1245c1ca3eb7ecccd8606bfb334f76", - 0x15141679af9a42a9228adc686f802fe183515180bed3de3933e1622668e06796 + 0xb445285e36eb120a47bd995ce7ecc07f73bf1ec99b5024ef14e87aa1bffd8b39, + 0x8f7241cd388505b0f964dd54243c968559ba603400ee71dea0738a9084f5cf50 ); // execute addPool, exodusSession: 7 vm.prank(ALICE); gatekeeper.verify( hex"3137142600000000000000000000000000000000000000000000000000000000000000070000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024d914cd4b000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000", - hex"04eb497652f4ad64ddd9223cd1af4785b37c6b2a41f8c1f54b906d595ab0d2b53305cd006238ca4eaf7eede77b3e2c0d1019e9f9d505fe80e86240e0d83051dcf2", - 0xa93dcb9c9c399973a17abc3b3667e37da716bdd5e9ed9c0b99d9fc869a886700 + 0x83cdbf2cee6f13d60c2261feed4d0643e847cfba6af316722538281c9cb433c8, + 0xdd0c8c1d6d154c951a4171ff9a40084afbfe5f7b3c70c0521e5b6605310e77cb ); // execute removePool, exodusSession: 8 vm.prank(ALICE); gatekeeper.verify( hex"3137142600000000000000000000000000000000000000000000000000000000000000080000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024a38dcbd0000000000000000000000000000000000000000000000000000000000000053900000000000000000000000000000000000000000000000000000000", - hex"0446039e3eec08f356c0a6e9fdd243aed6d840c1d9d973d1496db70499061055d45faf8e945d2fb87016cdcfda040df8fcaf22fe9a466dbdd4687cbfde7c87d0d8", - 0x110eedf82f6533d95a43a19de3da026c51557e552bd4c5b6f06ca94d6ab2c8db + 0x622a8a5d57b10682a90e1b92f797375a6bcbb78f30c45877ea570091af1b2831, + 0xd72cd8354a7be788b801e19994a8155f3938ef58005095b398bc96cd2dc77166 ); // execute close, exodusSession: 9 vm.prank(ALICE); gatekeeper.verify( hex"3137142600000000000000000000000000000000000000000000000000000000000000090000000000007a69010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000240aebeb4e00000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000", - hex"048da83909e645cf4313d00985c86bcbd24f584512f2279476767fb94829a2a9c7b95bcfeacc3bee2fe4710bfc2bcf2e72e58bcd37fc02293b660a7b70e2efd184", - 0x8a28d3b7b5db6564e4abb846bc662a69d9b52ed08bd2ce2dbc6af4e86167f55e + 0x0ad9c560affebaea5c589fe831033bac2d9c828aacf58559bbf5b2d00f7842b2, + 0x10121ffe0cc95cf3cbb4e92d72d61feec3e94045185cd7f3c5ce0d01e3a644ea ); // execute close, exodusSession: 10 vm.prank(ALICE); gatekeeper.verify( hex"31371426000000000000000000000000000000000000000000000000000000000000000a0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000144a0139f41000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000053900000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000000005390000000000000000000000000101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000230000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000", - hex"0417bd8b7509486284c1f613117c61abc39cee8a24422fce457099e430b805468be33547f272d8123e9aa6f8895babbaa3a3731eaeda7d8ad4286c9fb117034d21", - 0x0b71c4d8ca7748ec35257a42f26e09aaab9fa4a03e40d50a96bfdfdce10ce7e5 + 0xb354049d0012ef7ec3edac6aba453daf4bdc2d28fe1d88138f94459799e2343f, + 0x13a6f8b10007b41fa08c8efee85501fac2554571af99fe587b534fe28fdb82a3 ); // execute enable, exodusSession: 13 vm.prank(ALICE); gatekeeper.verify( hex"31371426000000000000000000000000000000000000000000000000000000000000000d0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064e4e33ef800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000101010101010101010101010101010101010101000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000", - hex"04f34417b947a4da097ca9596838430bf40587339fb42a09210ceb0dbbcfd98a99b1e8fd8f4d2301ee5b5d304e1d8b8e8b81ac14688f1e7de41d65c09a65975f01", - 0xa4084ea553df2f808c86437547550be910554d41d33a5d66a4643c9792c4f56f + 0x0716f763060cfd52339544a203d0e156a42370b0e22d78ea9bf8766b0b66682b, + 0xc2da93948f869c5102992bd1cbd70ef5f821ff522305c69d113faf2e89570ce7 ); // execute disable, exodusSession: 14 vm.prank(ALICE); gatekeeper.verify( hex"31371426000000000000000000000000000000000000000000000000000000000000000e0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044529918310000000000000000000000000000000000000000000000000000000000000003000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000", - hex"04f94dad10974c9f0b9307444dc4c660f1f169b25fd3ed9fd563df74714e73c2d4e92b3429505989327d449d9a68e6cce0f557574c92c0ca7bc8126dd710094e9e", - 0xb6b75ed763f4d06b9d7a7557ca8d095df656ca25db74645fb47a0b45d27ec501 + 0x7ed91b176c29b73a077e51de0c2a12f6df5e7e04862eb07f9c393f6fc1cd3a8f, + 0x798563362adaade33f39266bb3fa233ac9161ca55d532ca65d5b6d4d0f1edbd2 ); // execute forfeitReserves, exodusSession: 15 vm.prank(ALICE); gatekeeper.verify( hex"31371426000000000000000000000000000000000000000000000000000000000000000f0000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064f0de236c000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000001a4000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000", - hex"04af06146f4ca63ef11b82ad891d8e03525a11922316a7dd3f71ff4b6aa5ee6793d29e6af2355d26bc173bb52c1f5eb7d8b279ed40bef2d1cd521da33517b6d3cd", - 0x6343b047bb8fe39200758de1e874ddfaf296e1f9259f0b720a070a69e7a3ee08 + 0x7f90802deb959f3bea4aa2cda26dad5ec601fc6e45dcd941a19ee9ff57e3f571, + 0xf61bb645ce15a7e4d0a693e0e4defe1f58fa1b113818a083b582fce05ec728f5 ); // execute redeemReserve, exodusSession: 16 vm.prank(ALICE); gatekeeper.verify( hex"3137142600000000000000000000000000000000000000000000000000000000000000100000000000007a690101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000004482a21577000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000", - hex"041ff894074000f2d934cf3b136165766044b177e69de4c36fac4d1265b855e1a5b4b7b2b25400fbf4d5eb4619039ffc95555db216991d3050bb6fd966f6e3eeab", - 0x7d31ebf1e510616e541795b6448d387d2119b3fdd0124e5116c53726b6b1cc15 + 0x197fd53cb6c9c89e8689419c2ea745233487ba7666f896a2469fc5269c785160, + 0x79480d2dfee9c8dcdc2a28a22b3d49ed193c912390c0be655253028fd8ca883d ); // execute withdraw, exodusSession: 17 vm.prank(ALICE); gatekeeper.verify( hex"3137142600000000000000000000000000000000000000000000000000000000000000110000000000007a6901010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044f3fef3a3000000000000000000000000010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000001a400000000000000000000000000000000000000000000000000000000", - hex"04f31030cf8563dd976d1a823a84e43ebdcc13bb5e5e0d7a2ff372006c71e6ab3d4d0770771682dcd6eff9e13fb3d113b484d7384d08f247760b07149dca1aa234", - 0x06aad271d98e69d1ff18bf39e6713f347aba0df04d99bc4a9304b780431d12ae + 0x53a249b4952662c3a86a810cff1e530ba354761e4091dee9a8997279160b017b, + 0x8042a9b2521d07612ef0fdccaa98ce9561914b20bf75af49310fc36c240073c7 ); // execute auditReserves, exodusSession: 18 vm.prank(ALICE); gatekeeper.verify( hex"3137142600000000000000000000000000000000000000000000000000000000000000120000000000007a69010101010101010101010101010101010101010100000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000042b7ce50000000000000000000000000000000000000000000000000000000000", - hex"049e5d54fd32dcec64b20943a61763dc760b1e3e9d31948780e2193480d904984c0cdaa8074196c06104557b1a04de6aeeda135e0c3413192f9e4331f3b7447ff2", - 0x43ed5301b16b4b2bc91c28dcfbaecc9949a7fc8fe5c57dfef6229f62493da6d2 + 0xf1f4d62d27c3d0388b2298b621b23cd5791e1b97d4423ffc16b14e81ff0df97c, + 0xdbeed3eb94a829710147595c1b10f2ac6ec761c9721d8cc4711842c212ac517e ); address storageHistory = gatekeeper.storageHistory(); diff --git a/test/gatekeeper/GatekeeperRecall.t.sol b/test/gatekeeper/GatekeeperRecall.t.sol index 7a5cc44..cac373d 100644 --- a/test/gatekeeper/GatekeeperRecall.t.sol +++ b/test/gatekeeper/GatekeeperRecall.t.sol @@ -8,15 +8,10 @@ import {Ghost} from "../../src/GhstERC20.sol"; import {GhostAuthority} from "../../src/GhostAuthority.sol"; import {GhostTreasury} from "../../src/Treasury.sol"; import {GhostStaking} from "../../src/Staking.sol"; -import {GhostBondDepository} from "../../src/BondDepository.sol"; -import {ERC20Mock} from "../../src/mocks/ERC20Mock.sol"; import {WETH9} from "../../src/mocks/WETH9.sol"; import {GhostBondingCalculator} from "../../src/StandardBondingCalculator.sol"; import {Gatekeeper} from "../../src/Gatekeeper.sol"; - import {ITreasury} from "../../src/interfaces/ITreasury.sol"; -import {IGatekeeper} from "../../src/interfaces/IGatekeeper.sol"; -import {IERC20} from "@openzeppelin-contracts/token/ERC20/IERC20.sol"; contract GatekeeperRecallTest is Test { uint256 public constant TOTAL_INITIAL_SUPPLY = 5000000000000000; @@ -100,7 +95,8 @@ contract GatekeeperRecallTest is Test { function test_recallChainWorks() public { vm.startPrank(INITIALIZER); Gatekeeper gatekeeper = Gatekeeper(payable(staking.gatekeeper())); - gatekeeper.updatePublicKeyMetadata(0, 0x4e8c1fe96d6737cdabbcc96501d6656b9d0b659b3a528ef507f2d52bef29e157, 0); + gatekeeper.updatePublicKeyMetadata(0, 0x36ff5b7f0fc50100b563c6072e499980d6e6aa8528ea0ae6d776cf7e8e96c374, 0); + vm.stopPrank(); vm.startPrank(ALICE); @@ -126,9 +122,9 @@ contract GatekeeperRecallTest is Test { vm.txGasPrice(2 gwei); vm.startPrank(BOB, BOB); gatekeeper.verify( - hex"bf06188a000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000009536c70891000000000000000000000000000000000000000000020000000000007a6980000000", - hex"046566d4b0904bf35afd25dff583d53bd30e50f57cc790ad08377e0b85006b38b85046b527098f3dfdadc30d6623b6b1c4644306dd56d39f7c9d6b3b295d005c33", - 0x942fb44ad0422c197f9c3016ff7c7e574a9f86182c5485e39fc9bebf61228ad6 + hex"bf06188a0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000007a919134c0400000000000000000000000000000000000000000010000000000007a6900000000", + 0x938640689e6f52929acf2714c5c785e8e725b5df616c449a19bca8a8b300ec8b, + 0x15b8b8c2934ee96d6a83a24055d83ea4074d251c207584e66d9caf8d653cabf2 ); vm.stopPrank(); diff --git a/test/gatekeeper/GatekeeperWeaver.t.sol b/test/gatekeeper/GatekeeperWeaver.t.sol index 4891eb9..e83c75f 100644 --- a/test/gatekeeper/GatekeeperWeaver.t.sol +++ b/test/gatekeeper/GatekeeperWeaver.t.sol @@ -95,14 +95,14 @@ contract GatekeeperWeaver is Gatekeeper { unchecked { ++i; } } - computedHash = Hashes.efficientKeccak256(computedHash); + computedHash = Hashes.efficientKeccak256Prefixed(computedHash); i = 0; for (; i < proof.length; ) { if (slotIndex % 2 == 0) { - computedHash = Hashes.efficientKeccak256(computedHash, proof[i]); + computedHash = Hashes.efficientKeccak256Prefixed(computedHash, proof[i]); } else { - computedHash = Hashes.efficientKeccak256(proof[i], computedHash); + computedHash = Hashes.efficientKeccak256Prefixed(proof[i], computedHash); } slotIndex >>= 1; unchecked { ++i; }