Skip to content

Commit 61f39fc

Browse files
authored
fix: address tmnt 158 (#16456)
Please read [contributing guidelines](CONTRIBUTING.md) and remove this line. For audit-related pull requests, please use the [audit PR template](?expand=1&template=audit.md).
2 parents 7297d7e + efd6a3e commit 61f39fc

6 files changed

Lines changed: 78 additions & 41 deletions

File tree

l1-contracts/src/governance/GSE.sol

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,6 @@ contract GSECore is IGSECore, Ownable {
184184
// intended.
185185
IERC20 public immutable ASSET;
186186

187-
// the `gap` pushes the `checkProofOfPossession` into its own slot
188-
// so we don't have the trouble of being in the middle of a slot
189-
uint256 private gap = 0;
190-
191-
// @note Always true, exists to override to false for testing only.
192-
bool public checkProofOfPossession = true;
193-
194187
// The GSE's history of rollups.
195188
Checkpoints.Trace224 internal rollups;
196189
// Mapping from instance address to its historical attester information.
@@ -332,28 +325,7 @@ contract GSECore is IGSECore, Ownable {
332325
instances[recipientInstance].attesters.add(_attester), Errors.GSE__AlreadyRegistered(recipientInstance, _attester)
333326
);
334327

335-
if (checkProofOfPossession) {
336-
// Make sure the attester has not registered before
337-
G1Point memory previouslyRegisteredPoint = configOf[_attester].publicKey;
338-
require(
339-
(previouslyRegisteredPoint.x == 0 && previouslyRegisteredPoint.y == 0),
340-
Errors.GSE__CannotChangePublicKeys(previouslyRegisteredPoint.x, previouslyRegisteredPoint.y)
341-
);
342-
343-
// Make sure the incoming point has not been seen before
344-
// NOTE: we only need to check for the existence of Pk1, and not also for Pk2,
345-
// as the Pk2 will be constrained to have the same underlying secret key as part of the proofOfPossession,
346-
// so existence/correctness of Pk2 is implied by existence/correctness of Pk1.
347-
bytes32 hashedIncomingPoint = keccak256(abi.encodePacked(_publicKeyInG1.x, _publicKeyInG1.y));
348-
require((!ownedPKs[hashedIncomingPoint]), Errors.GSE__ProofOfPossessionAlreadySeen(hashedIncomingPoint));
349-
350-
require(
351-
BN254Lib.proofOfPossession(_publicKeyInG1, _publicKeyInG2, _proofOfPossession),
352-
Errors.GSE__InvalidProofOfPossession()
353-
);
354-
355-
ownedPKs[hashedIncomingPoint] = true;
356-
}
328+
_checkProofOfPossession(_attester, _publicKeyInG1, _publicKeyInG2, _proofOfPossession);
357329

358330
// This is the ONLY place where we set the configuration for an attester.
359331
// This means that their withdrawer and public keys are set once, globally.
@@ -616,6 +588,33 @@ contract GSECore is IGSECore, Ownable {
616588
getGovernance().vote(_proposalId, _amount, _support);
617589
}
618590

591+
function _checkProofOfPossession(
592+
address _attester,
593+
G1Point memory _publicKeyInG1,
594+
G2Point memory _publicKeyInG2,
595+
G1Point memory _proofOfPossession
596+
) internal virtual {
597+
// Make sure the attester has not registered before
598+
G1Point memory previouslyRegisteredPoint = configOf[_attester].publicKey;
599+
require(
600+
(previouslyRegisteredPoint.x == 0 && previouslyRegisteredPoint.y == 0),
601+
Errors.GSE__CannotChangePublicKeys(previouslyRegisteredPoint.x, previouslyRegisteredPoint.y)
602+
);
603+
604+
// Make sure the incoming point has not been seen before
605+
// NOTE: we only need to check for the existence of Pk1, and not also for Pk2,
606+
// as the Pk2 will be constrained to have the same underlying secret key as part of the proofOfPossession,
607+
// so existence/correctness of Pk2 is implied by existence/correctness of Pk1.
608+
bytes32 hashedIncomingPoint = keccak256(abi.encodePacked(_publicKeyInG1.x, _publicKeyInG1.y));
609+
require((!ownedPKs[hashedIncomingPoint]), Errors.GSE__ProofOfPossessionAlreadySeen(hashedIncomingPoint));
610+
ownedPKs[hashedIncomingPoint] = true;
611+
612+
require(
613+
BN254Lib.proofOfPossession(_publicKeyInG1, _publicKeyInG2, _proofOfPossession),
614+
Errors.GSE__InvalidProofOfPossession()
615+
);
616+
}
617+
619618
function _pendingThrough(uint256 _proposalId) internal view returns (Timestamp) {
620619
return getGovernance().getProposal(_proposalId).pendingThroughMemory();
621620
}

l1-contracts/test/GSEWithSkip.sol

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright 2024 Aztec Labs.
3+
pragma solidity >=0.8.27;
4+
5+
import {GSE} from "@aztec/governance/GSE.sol";
6+
import {IERC20} from "@oz/token/ERC20/IERC20.sol";
7+
import {BN254Lib, G1Point, G2Point} from "@aztec/shared/libraries/BN254Lib.sol";
8+
9+
contract GSEWithSkip is GSE {
10+
// the `gap` pushes the `checkProofOfPossession` into its own slot
11+
// so we don't have the trouble of being in the middle of a slot
12+
uint256 private gap = 0;
13+
14+
// @note Always true, exists to override to false for testing only.
15+
bool public checkProofOfPossession = true;
16+
17+
constructor(address __owner, IERC20 _asset, uint256 _activationThreshold, uint256 _ejectionThreshold)
18+
GSE(__owner, _asset, _activationThreshold, _ejectionThreshold)
19+
{}
20+
21+
function setCheckProofOfPossession(bool _shouldCheck) external {
22+
checkProofOfPossession = _shouldCheck;
23+
}
24+
25+
function _checkProofOfPossession(
26+
address _attester,
27+
G1Point memory _publicKeyInG1,
28+
G2Point memory _publicKeyInG2,
29+
G1Point memory _proofOfPossession
30+
) internal override {
31+
if (checkProofOfPossession) {
32+
super._checkProofOfPossession(_attester, _publicKeyInG1, _publicKeyInG2, _proofOfPossession);
33+
}
34+
}
35+
}

l1-contracts/test/builder/GseBuilder.sol

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
pragma solidity >=0.8.27;
55

66
import {GSE} from "@aztec/governance/GSE.sol";
7+
import {GSEWithSkip} from "@test/GSEWithSkip.sol";
78
import {TestBase} from "@test/base/Base.sol";
89
import {TestConstants} from "@test/harnesses/TestConstants.sol";
910

@@ -70,12 +71,12 @@ contract GSEBuilder is TestBase {
7071
}
7172

7273
if (address(config.gse) == address(0)) {
73-
config.gse =
74-
new GSE(address(this), config.testERC20, TestConstants.ACTIVATION_THRESHOLD, TestConstants.EJECTION_THRESHOLD);
75-
vm.label(address(config.gse), "GSE");
76-
stdstore.target(address(config.gse)).sig("checkProofOfPossession()").checked_write(
77-
config.flags.checkProofOfPossession
74+
config.gse = new GSEWithSkip(
75+
address(this), config.testERC20, TestConstants.ACTIVATION_THRESHOLD, TestConstants.EJECTION_THRESHOLD
7876
);
77+
vm.label(address(config.gse), "GSE");
78+
79+
GSEWithSkip(address(config.gse)).setCheckProofOfPossession(config.flags.checkProofOfPossession);
7980
}
8081

8182
if (address(config.registry) == address(0)) {

l1-contracts/test/builder/RollupBuilder.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {Test} from "forge-std/Test.sol";
1919
import {MultiAdder, CheatDepositArgs} from "@aztec/mock/MultiAdder.sol";
2020
import {CoinIssuer} from "@aztec/governance/CoinIssuer.sol";
2121
import {stdStorage, StdStorage} from "forge-std/Test.sol";
22+
import {GSEWithSkip} from "@test/GSEWithSkip.sol";
2223

2324
// Stack the layers to avoid the stack too deep 🧌
2425
struct ConfigFlags {
@@ -228,12 +229,11 @@ contract RollupBuilder is Test {
228229
}
229230

230231
if (address(config.gse) == address(0)) {
231-
config.gse =
232-
new GSE(address(this), config.testERC20, TestConstants.ACTIVATION_THRESHOLD, TestConstants.EJECTION_THRESHOLD);
233-
234-
stdstore.target(address(config.gse)).sig("checkProofOfPossession()").checked_write(
235-
config.flags.checkProofOfPossession
232+
config.gse = new GSEWithSkip(
233+
address(this), config.testERC20, TestConstants.ACTIVATION_THRESHOLD, TestConstants.EJECTION_THRESHOLD
236234
);
235+
236+
GSEWithSkip(address(config.gse)).setCheckProofOfPossession(config.flags.checkProofOfPossession);
237237
}
238238

239239
if (address(config.registry) == address(0)) {

l1-contracts/test/governance/gse/gse/depositBN254.t.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {Errors} from "@aztec/governance/libraries/Errors.sol";
66
import {AttesterConfig} from "@aztec/governance/GSE.sol";
77
import {stdStorage, StdStorage} from "forge-std/Test.sol";
88
import {WithGSE} from "./base.sol";
9+
import {GSEWithSkip} from "@test/GSEWithSkip.sol";
910

1011
contract DepositBN254Test is WithGSE {
1112
using stdStorage for StdStorage;
@@ -23,7 +24,7 @@ contract DepositBN254Test is WithGSE {
2324

2425
function setUp() public override {
2526
super.setUp();
26-
stdstore.target(address(gse)).sig("checkProofOfPossession()").checked_write(true);
27+
GSEWithSkip(address(gse)).setCheckProofOfPossession(true);
2728
// See yarn-project/ethereum/src/test/bn254_registration.test.ts for construction of pk2
2829
// Prefilling here, and the rest of the data will be generated using the helper
2930
// generateProofsOfPossession()

l1-contracts/test/staking/invalidDeposit.t.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {Rollup} from "@aztec/core/Rollup.sol";
1313
import {G1Point, G2Point} from "@aztec/shared/libraries/BN254Lib.sol";
1414
import {BN254Fixtures} from "../shared/BN254Fixtures.t.sol";
1515
import {stdStorage, StdStorage} from "forge-std/Test.sol";
16+
import {GSEWithSkip} from "@test/GSEWithSkip.sol";
1617

1718
contract InvalidPointsFlushEntryQueueTest is StakingBase, BN254Fixtures {
1819
using stdStorage for StdStorage;
@@ -31,7 +32,7 @@ contract InvalidPointsFlushEntryQueueTest is StakingBase, BN254Fixtures {
3132
StakingBase.setUp();
3233

3334
GSE gse = staking.getGSE();
34-
stdstore.target(address(gse)).sig("checkProofOfPossession()").checked_write(true);
35+
GSEWithSkip(address(gse)).setCheckProofOfPossession(true);
3536

3637
StakingQueueConfig memory stakingQueueConfig = StakingQueueConfig({
3738
bootstrapValidatorSetSize: 0,

0 commit comments

Comments
 (0)