From b57b9da9db45279c6d4cbdf6115eea7ac0c7bcd7 Mon Sep 17 00:00:00 2001 From: vedhavyas Date: Mon, 2 Dec 2024 15:39:00 +0530 Subject: [PATCH] ensure only deployer can update the first guardian set --- contracts/wormhole/wormhole-core-v2.clar | 9 +++++++- unit-tests/pyth/oracle.test.ts | 3 ++- unit-tests/pyth/pnau.test.ts | 6 ++++-- unit-tests/pyth/ptgm.test.ts | 26 +++++++++++++++--------- unit-tests/wormhole/vaa.test.ts | 25 ++++++++++++++--------- 5 files changed, 45 insertions(+), 24 deletions(-) diff --git a/contracts/wormhole/wormhole-core-v2.clar b/contracts/wormhole/wormhole-core-v2.clar index 0f47bf1..85ececf 100644 --- a/contracts/wormhole/wormhole-core-v2.clar +++ b/contracts/wormhole/wormhole-core-v2.clar @@ -68,6 +68,8 @@ (define-constant ERR_GSU_CHECK_INDEX (err u1304)) ;; Guardian Set Update emission payload unauthorized (define-constant ERR_GSU_CHECK_EMITTER (err u1305)) +;; First guardian set is not being updated by the deployer +(define-constant ERR_NOT_DEPLOYER (err u1306)) ;; Guardian set upgrade emitting address (define-constant GSU-EMITTING-ADDRESS 0x0000000000000000000000000000000000000000000000000000000000000004) @@ -81,6 +83,8 @@ ;; Guardian Set Update uncompressed public keys invalid (define-data-var guardian-set-initialized bool false) +;; Contract deployer +(define-constant deployer contract-caller) ;; Keep track of the active guardian set-id (define-data-var active-guardian-set-id uint u0) @@ -195,7 +199,10 @@ (define-public (update-guardians-set (guardian-set-vaa (buff 2048)) (uncompressed-public-keys (list 19 (buff 64)))) (let ((vaa (if (var-get guardian-set-initialized) (try! (parse-and-verify-vaa guardian-set-vaa)) - (get vaa (try! (parse-vaa guardian-set-vaa))))) + (begin + (asserts! (is-eq contract-caller deployer) ERR_NOT_DEPLOYER) + (get vaa (try! (parse-vaa guardian-set-vaa))) + ))) (cursor-guardians-data (try! (parse-and-verify-guardians-set (get payload vaa)))) (set-id (get new-index (get value cursor-guardians-data))) (eth-addresses (get guardians-eth-addresses (get value cursor-guardians-data))) diff --git a/unit-tests/pyth/oracle.test.ts b/unit-tests/pyth/oracle.test.ts index 607a065..9ee030d 100644 --- a/unit-tests/pyth/oracle.test.ts +++ b/unit-tests/pyth/oracle.test.ts @@ -11,6 +11,7 @@ const wormholeCoreContractName = "wormhole-core-v2"; describe("pyth-oracle-v2::decode-and-verify-price-feeds mainnet VAAs", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; let block: ParsedTransactionResult[] | undefined = undefined; @@ -18,7 +19,7 @@ describe("pyth-oracle-v2::decode-and-verify-price-feeds mainnet VAAs", () => { // Before starting the test suite, we have to setup the guardian set. beforeEach(async () => { block = wormhole.applyMainnetGuardianSetUpdates( - sender, + deployer, wormholeCoreContractName, ); }); diff --git a/unit-tests/pyth/pnau.test.ts b/unit-tests/pyth/pnau.test.ts index 369d141..51cdbeb 100644 --- a/unit-tests/pyth/pnau.test.ts +++ b/unit-tests/pyth/pnau.test.ts @@ -11,6 +11,7 @@ const wormholeCoreContractName = "wormhole-core-v2"; describe("pyth-pnau-decoder-v1::decode-and-verify-price-feeds success", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; const guardianSet = wormhole.generateGuardianSetKeychain(19); let pricesUpdates = pyth.buildPriceUpdateBatch([ @@ -35,7 +36,7 @@ describe("pyth-pnau-decoder-v1::decode-and-verify-price-feeds success", () => { wormhole.applyGuardianSetUpdate( guardianSet, 1, - sender, + deployer, wormholeCoreContractName, ); @@ -132,6 +133,7 @@ describe("pyth-pnau-decoder-v1::decode-and-verify-price-feeds success", () => { describe("pyth-pnau-decoder-v1::decode-and-verify-price-feeds failures", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; const guardianSet = wormhole.generateGuardianSetKeychain(19); let pricesUpdates = pyth.buildPriceUpdateBatch([ @@ -170,7 +172,7 @@ describe("pyth-pnau-decoder-v1::decode-and-verify-price-feeds failures", () => { wormhole.applyGuardianSetUpdate( guardianSet, 1, - sender, + deployer, wormholeCoreContractName, ); diff --git a/unit-tests/pyth/ptgm.test.ts b/unit-tests/pyth/ptgm.test.ts index c47df9e..02fa140 100644 --- a/unit-tests/pyth/ptgm.test.ts +++ b/unit-tests/pyth/ptgm.test.ts @@ -15,6 +15,7 @@ const initialFeeRecipient = "ST3CRXBDXQ2N5P7E25Q39MEX1HSMRDSEAP1JST19D"; describe("pyth-governance-v1::update-fee-value mainnet VAAs", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; let block: ParsedTransactionResult[] | undefined = undefined; @@ -22,7 +23,7 @@ describe("pyth-governance-v1::update-fee-value mainnet VAAs", () => { // Before starting the test suite, we have to setup the guardian set. beforeEach(async () => { block = wormhole.applyMainnetGuardianSetUpdates( - sender, + deployer, wormholeCoreContractName, ); }); @@ -74,6 +75,7 @@ describe("pyth-governance-v1::update-fee-value mainnet VAAs", () => { describe("pyth-governance-v1::update-fee-value", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; const guardianSet = wormhole.generateGuardianSetKeychain(19); let updateFeeValue = { @@ -87,7 +89,7 @@ describe("pyth-governance-v1::update-fee-value", () => { wormhole.applyGuardianSetUpdate( guardianSet, 1, - sender, + deployer, wormholeCoreContractName, ); }); @@ -160,6 +162,7 @@ describe("pyth-governance-v1::update-fee-value", () => { describe("pyth-governance-v1::update-fee-recipient", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; const guardianSet = wormhole.generateGuardianSetKeychain(19); let updateFeeRecipient = { @@ -172,7 +175,7 @@ describe("pyth-governance-v1::update-fee-recipient", () => { wormhole.applyGuardianSetUpdate( guardianSet, 1, - sender, + deployer, wormholeCoreContractName, ); }); @@ -253,7 +256,7 @@ describe("pyth-governance-v1::update-wormhole-core-contract", () => { wormhole.applyGuardianSetUpdate( guardianSet, 1, - sender, + deployer, wormholeCoreContractName, ); }); @@ -369,7 +372,7 @@ describe("pyth-governance-v1::update-pyth-decoder-contract", () => { wormhole.applyGuardianSetUpdate( guardianSet, 1, - sender, + deployer, wormholeCoreContractName, ); }); @@ -498,7 +501,7 @@ describe("pyth-governance-v1::update-pyth-store-contract", () => { wormhole.applyGuardianSetUpdate( guardianSet, 1, - sender, + deployer, wormholeCoreContractName, ); }); @@ -625,7 +628,7 @@ describe("pyth-governance-v1::update-pyth-oracle-contract", () => { wormhole.applyGuardianSetUpdate( guardianSet, 1, - sender, + deployer, wormholeCoreContractName, ); }); @@ -717,6 +720,7 @@ describe("pyth-governance-v1::update-pyth-oracle-contract", () => { describe("pyth-governance-v1::update-prices-data-sources", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; const guardianSet = wormhole.generateGuardianSetKeychain(19); let updatePricesDataSources = [ @@ -740,7 +744,7 @@ describe("pyth-governance-v1::update-prices-data-sources", () => { wormhole.applyGuardianSetUpdate( guardianSet, 1, - sender, + deployer, wormholeCoreContractName, ); }); @@ -805,6 +809,7 @@ describe("pyth-governance-v1::update-prices-data-sources", () => { describe("pyth-governance-v1::update-governance-data-source", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; const guardianSet = wormhole.generateGuardianSetKeychain(19); let updateGovernanceDataSource = { @@ -819,7 +824,7 @@ describe("pyth-governance-v1::update-governance-data-source", () => { wormhole.applyGuardianSetUpdate( guardianSet, 1, - sender, + deployer, wormholeCoreContractName, ); @@ -1049,6 +1054,7 @@ describe("pyth-governance-v1::update-governance-data-source", () => { describe("pyth-governance-v1::update-stale-price-threshold", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; const guardianSet = wormhole.generateGuardianSetKeychain(19); let updateStalePriceThreshold = { @@ -1061,7 +1067,7 @@ describe("pyth-governance-v1::update-stale-price-threshold", () => { wormhole.applyGuardianSetUpdate( guardianSet, 1, - sender, + deployer, wormholeCoreContractName, ); }); diff --git a/unit-tests/wormhole/vaa.test.ts b/unit-tests/wormhole/vaa.test.ts index 4231c45..193438a 100644 --- a/unit-tests/wormhole/vaa.test.ts +++ b/unit-tests/wormhole/vaa.test.ts @@ -62,6 +62,7 @@ describe("wormhole-core-v2::parse-vaa success", () => { describe("wormhole-core-v2::update-guardians-set failures", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; const keychain = wormhole.generateGuardianSetKeychain(19); @@ -93,7 +94,7 @@ describe("wormhole-core-v2::update-guardians-set failures", () => { contractName, `update-guardians-set`, [Cl.buffer(vaa), Cl.list(uncompressedPublicKey)], - sender, + deployer, ); expect(res.result).toBeErr(Cl.uint(1303)); }); @@ -126,7 +127,7 @@ describe("wormhole-core-v2::update-guardians-set failures", () => { contractName, `update-guardians-set`, [Cl.buffer(vaa), Cl.list(uncompressedPublicKey)], - sender, + deployer, ); expect(res.result).toBeErr(Cl.uint(1302)); }); @@ -159,7 +160,7 @@ describe("wormhole-core-v2::update-guardians-set failures", () => { contractName, `update-guardians-set`, [Cl.buffer(vaa), Cl.list(uncompressedPublicKey)], - sender, + deployer, ); expect(res.result).toBeErr(Cl.uint(1304)); }); @@ -195,7 +196,7 @@ describe("wormhole-core-v2::update-guardians-set failures", () => { contractName, `update-guardians-set`, [Cl.buffer(vaa), Cl.list(uncompressedPublicKey)], - sender, + deployer, ); expect(res.result).toBeErr(Cl.uint(1301)); }); @@ -232,7 +233,7 @@ describe("wormhole-core-v2::update-guardians-set failures", () => { contractName, `update-guardians-set`, [Cl.buffer(vaa), Cl.list(uncompressedPublicKey)], - sender, + deployer, ); expect(res.result).toBeErr(Cl.uint(1305)); }); @@ -269,7 +270,7 @@ describe("wormhole-core-v2::update-guardians-set failures", () => { contractName, `update-guardians-set`, [Cl.buffer(vaa), Cl.list(uncompressedPublicKey)], - sender, + deployer, ); expect(res.result).toBeErr(Cl.uint(1305)); }); @@ -277,6 +278,7 @@ describe("wormhole-core-v2::update-guardians-set failures", () => { describe("wormhole-core-v2::update-guardians-set success", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; const guardianSet1Keys = wormhole.generateGuardianSetKeychain(19); const guardianSet2Keys = wormhole.generateGuardianSetKeychain(19); @@ -287,7 +289,7 @@ describe("wormhole-core-v2::update-guardians-set success", () => { let [result, vaaHeader, vaaBody] = wormhole.applyGuardianSetUpdate( guardianSet1Keys, 1, - sender, + deployer, contractName, ); let [serializeVaaToClarityValue, _] = wormhole.serializeVaaToClarityValue( @@ -441,13 +443,14 @@ describe("wormhole-core-v2::update-guardians-set success", () => { describe("wormhole-core-v2::parse-and-verify-vaa success", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; const guardianSet1Keys = wormhole.generateGuardianSetKeychain(19); // const guardianSet2Keys = wormhole.generateGuardianSetKeychain(19); // Before starting the test suite, we have to setup the guardian set. beforeEach(async () => { - wormhole.applyGuardianSetUpdate(guardianSet1Keys, 1, sender, contractName); + wormhole.applyGuardianSetUpdate(guardianSet1Keys, 1, deployer, contractName); }); it("should succeed if the vaa is valid", () => { @@ -527,12 +530,13 @@ describe("wormhole-core-v2::parse-and-verify-vaa success", () => { describe("wormhole-core-v2::parse-and-verify-vaa failures", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; const guardianSet1Keys = wormhole.generateGuardianSetKeychain(19); // Before starting the test suite, we have to setup the guardian set. beforeEach(async () => { - wormhole.applyGuardianSetUpdate(guardianSet1Keys, 1, sender, contractName); + wormhole.applyGuardianSetUpdate(guardianSet1Keys, 1, deployer, contractName); }); it("should fail if the version is invalid", () => { @@ -664,12 +668,13 @@ describe("wormhole-core-v2::parse-and-verify-vaa failures", () => { describe("wormhole-core-v2::update-guardians-set mainnet guardian rotations", () => { const accounts = simnet.getAccounts(); + const deployer = accounts.get("deployer")!; const sender = accounts.get("wallet_1")!; let block: ParsedTransactionResult[] | undefined = undefined; // Before starting the test suite, we have to setup the guardian set. beforeEach(async () => { - block = wormhole.applyMainnetGuardianSetUpdates(sender, contractName); + block = wormhole.applyMainnetGuardianSetUpdates(deployer, contractName); }); it("should succeed handling the 2 guardians rotations", () => {