From 373144a1ef3920518c0cb2dc0365cc3f8f2c1813 Mon Sep 17 00:00:00 2001 From: Promethea Raschke Date: Thu, 3 Aug 2023 16:01:38 +0100 Subject: [PATCH 1/3] Clean up tests and add some unhappy paths --- .../solana/tests/02__wormholeGateway.ts | 316 +++++++++++------- .../solana/tests/helpers/tbtcHelpers.ts | 14 +- .../tests/helpers/wormholeGatewayHelpers.ts | 32 ++ 3 files changed, 230 insertions(+), 132 deletions(-) diff --git a/cross-chain/solana/tests/02__wormholeGateway.ts b/cross-chain/solana/tests/02__wormholeGateway.ts index 9b4d712a7..09bc6e025 100644 --- a/cross-chain/solana/tests/02__wormholeGateway.ts +++ b/cross-chain/solana/tests/02__wormholeGateway.ts @@ -1,17 +1,25 @@ import * as mock from "@certusone/wormhole-sdk/lib/cjs/mock"; import * as tokenBridge from "@certusone/wormhole-sdk/lib/cjs/solana/tokenBridge"; import * as coreBridge from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole"; -import { NodeWallet } from "@certusone/wormhole-sdk/lib/cjs/solana"; import { parseTokenTransferVaa, postVaaSolana, redeemOnSolana, tryNativeToHexString } from "@certusone/wormhole-sdk"; + import * as anchor from "@coral-xyz/anchor"; import { Program, AnchorError } from "@coral-xyz/anchor"; import * as spl from "@solana/spl-token"; +import * as web3 from '@solana/web3.js'; import { expect } from 'chai'; + import { WormholeGateway } from "../target/types/wormhole_gateway"; + import { generatePayer, getOrCreateTokenAccount } from "./helpers/utils"; -import { getCustodianPDA, getTokenBridgeRedeemerPDA, getTokenBridgeSenderPDA, getWrappedTbtcTokenPDA } from "./helpers/wormholeGatewayHelpers"; +import { + getCustodianPDA, + getTokenBridgeRedeemerPDA, + getTokenBridgeSenderPDA, + getWrappedTbtcTokenPDA, + mockSignAndPostVaa +} from "./helpers/wormholeGatewayHelpers"; import * as tbtc from "./helpers/tbtcHelpers"; -import { web3 } from "@coral-xyz/anchor"; import { Tbtc } from "../target/types/tbtc"; const SOLANA_CORE_BRIDGE_ADDRESS = "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth"; @@ -22,7 +30,7 @@ const ETHEREUM_TBTC_ADDRESS = "0x18084fbA666a33d37592fA2633fD49a74DD93a88"; const GUARDIAN_SET_INDEX = 3; -async function setup( +export async function setupGateway( program: Program, tbtcProgram: Program, authority, @@ -37,20 +45,20 @@ async function setup( const wrappedTbtcMint = tokenBridge.deriveWrappedMintKey(SOLANA_TOKEN_BRIDGE_ADDRESS, 2, ETHEREUM_TBTC_ADDRESS); await program.methods - .initialize(new anchor.BN(mintingLimit)) - .accounts({ - authority: authority.publicKey, - custodian, - tbtcMint, - wrappedTbtcMint, - wrappedTbtcToken: gatewayWrappedTbtcToken, - tokenBridgeSender, - tokenBridgeRedeemer, - }) - .rpc(); + .initialize(new anchor.BN(mintingLimit)) + .accounts({ + authority: authority.publicKey, + custodian, + tbtcMint, + wrappedTbtcMint, + wrappedTbtcToken: gatewayWrappedTbtcToken, + tokenBridgeSender, + tokenBridgeRedeemer, + }) + .rpc(); } -async function checkState( +export async function checkCustodianState( program: Program, expectedAuthority, expectedMintingLimit, @@ -63,6 +71,72 @@ async function checkState( expect(custodianState.authority).to.eql(expectedAuthority.publicKey); } +export async function bridgeToSolana( + amount, + connection, + payer, + ethereumTokenBridge, +): Promise { + const wrappedTbtcMint = tokenBridge.deriveWrappedMintKey(SOLANA_TOKEN_BRIDGE_ADDRESS, 2, ETHEREUM_TBTC_ADDRESS); + const wrappedTbtcToken = await getOrCreateTokenAccount(connection, payer, wrappedTbtcMint, payer.publicKey); + + // Bridge tbtc to token account. + const published = ethereumTokenBridge.publishTransferTokens( + tryNativeToHexString(ETHEREUM_TBTC_ADDRESS, "ethereum"), + 2, + amount, + 1, + wrappedTbtcToken.address.toBuffer().toString("hex"), + BigInt(0), + 0, + 0 + ); + + const signedVaa = await mockSignAndPostVaa(connection, payer, published); + const tx = await redeemOnSolana( + connection, + SOLANA_CORE_BRIDGE_ADDRESS, + SOLANA_TOKEN_BRIDGE_ADDRESS, + payer.publicKey, + signedVaa, + ); + await web3.sendAndConfirmTransaction(connection, tx, [payer]); + return wrappedTbtcToken; +} + +export async function depositWormholeTbtc( + program: Program, + tbtcProgram, + amount, + recipientWrappedToken, + recipientToken, + payer, + minterInfo, +) { + const [custodian,] = getCustodianPDA(program); + const [tbtcMint,] = tbtc.getTokenPDA(tbtcProgram); + const [tbtcConfig,] = tbtc.getConfigPDA(tbtcProgram); + const [wrappedTbtcToken,] = getWrappedTbtcTokenPDA(program); + const wrappedTbtcMint = tokenBridge.deriveWrappedMintKey(SOLANA_TOKEN_BRIDGE_ADDRESS, 2, ETHEREUM_TBTC_ADDRESS); + + await program.methods + .depositWormholeTbtc(new anchor.BN(amount)) + .accounts({ + custodian, + wrappedTbtcToken, + wrappedTbtcMint, + tbtcMint, + recipientWrappedToken, + recipientToken, + recipient: payer.publicKey, + tbtcConfig, + minterInfo, + tbtcProgram: tbtcProgram.programId, + }) + .signers(tbtc.maybeAuthorityAnd(payer, [])) + .rpc(); +} + describe("wormhole-gateway", () => { // Configure the client to use the local cluster. anchor.setProvider(anchor.AnchorProvider.env()); @@ -91,6 +165,8 @@ describe("wormhole-gateway", () => { const ethereumTokenBridge = new mock.MockEthereumTokenBridge(ETHEREUM_TOKEN_BRIDGE_ADDRESS); + const wrappedTbtcMint = tokenBridge.deriveWrappedMintKey(SOLANA_TOKEN_BRIDGE_ADDRESS, 2, ETHEREUM_TBTC_ADDRESS); + it('check core bridge and token bridge', async () => { // Check core bridge guardian set. const guardianSetData = await coreBridge.getGuardianSet(connection, SOLANA_CORE_BRIDGE_ADDRESS, GUARDIAN_SET_INDEX); @@ -100,40 +176,16 @@ describe("wormhole-gateway", () => { const payer = await generatePayer(connection, authority.payer); // Check wrapped tBTC mint. - const wrappedTbtcMint = tokenBridge.deriveWrappedMintKey(SOLANA_TOKEN_BRIDGE_ADDRESS, 2, ETHEREUM_TBTC_ADDRESS); const mintData = await spl.getMint(connection, wrappedTbtcMint); expect(mintData.decimals).to.equal(8); expect(mintData.supply).to.equal(BigInt(90)); - const wrappedTbtcToken = await getOrCreateTokenAccount(connection, payer, wrappedTbtcMint, payer.publicKey); - - // Bridge tbtc to token account. - const published = ethereumTokenBridge.publishTransferTokens( - tryNativeToHexString(ETHEREUM_TBTC_ADDRESS, "ethereum"), - 2, - BigInt("100000000000"), - 1, - wrappedTbtcToken.address.toBuffer().toString("hex"), - BigInt(0), - 0, - 0 - ); - - const signedVaa = await mockSignAndPostVaa(connection, payer, published); - - const tx = await redeemOnSolana( - connection, - SOLANA_CORE_BRIDGE_ADDRESS, - SOLANA_TOKEN_BRIDGE_ADDRESS, - payer.publicKey, - signedVaa, - ); - await web3.sendAndConfirmTransaction(connection, tx, [payer]); + await bridgeToSolana(BigInt("100000000000"), connection, payer, ethereumTokenBridge); }); it('setup', async () => { - await setup(program, tbtcProgram, authority, 10000); - await checkState(program, authority, 10000); + await setupGateway(program, tbtcProgram, authority, 10000); + await checkCustodianState(program, authority, 10000); await tbtc.checkState(tbtcProgram, authority, 1, 2, 1500); }); @@ -145,81 +197,45 @@ describe("wormhole-gateway", () => { authority: authority.publicKey }) .rpc(); - await checkState(program, authority, 20000); + await checkCustodianState(program, authority, 20000); }); it('deposit wrapped tokens', async () => { - const [custodian,] = getCustodianPDA(program); - const minterInfo = await tbtc.addMinter(tbtcProgram, authority, custodian); - // Set up new wallet const payer = await generatePayer(connection, authority.payer); - - // Check wrapped tBTC mint. - const wrappedTbtcMint = tokenBridge.deriveWrappedMintKey(SOLANA_TOKEN_BRIDGE_ADDRESS, 2, ETHEREUM_TBTC_ADDRESS); - const wrappedTbtcToken = await getOrCreateTokenAccount(connection, payer, wrappedTbtcMint, payer.publicKey); - - // Bridge tbtc to token account. - const published = ethereumTokenBridge.publishTransferTokens( - tryNativeToHexString(ETHEREUM_TBTC_ADDRESS, "ethereum"), - 2, - BigInt("100000000000"), - 1, - wrappedTbtcToken.address.toBuffer().toString("hex"), - BigInt(0), - 0, - 0 - ); - - const signedVaa = await mockSignAndPostVaa(connection, payer, published); - - const tx = await redeemOnSolana( - connection, - SOLANA_CORE_BRIDGE_ADDRESS, - SOLANA_TOKEN_BRIDGE_ADDRESS, - payer.publicKey, - signedVaa, + const minterInfo = await tbtc.addMinter(tbtcProgram, authority, custodian); + const wrappedTbtcToken = await bridgeToSolana(BigInt("100000000000"), connection, payer, ethereumTokenBridge); + const recipientToken = await getOrCreateTokenAccount(connection, payer, tbtcMint, payer.publicKey); + + await depositWormholeTbtc( + program, + tbtcProgram, + 500, + wrappedTbtcToken.address, + recipientToken.address, + payer, + minterInfo ); - await web3.sendAndConfirmTransaction(connection, tx, [payer]); + + await tbtc.checkState(tbtcProgram, authority, 2, 2, 2000); + }); + it('won\'t deposit wrapped tokens over the minting limit', async () => { + const minterInfo = tbtc.getMinterPDA(tbtcProgram, custodian)[0]; + const payer = await generatePayer(connection, authority.payer); + const wrappedTbtcToken = await bridgeToSolana(BigInt("100000000000"), connection, payer, ethereumTokenBridge); const recipientToken = await getOrCreateTokenAccount(connection, payer, tbtcMint, payer.publicKey); - await program.methods - .depositWormholeTbtc(new anchor.BN(500)) - .accounts({ - custodian, - wrappedTbtcToken: gatewayWrappedTbtcToken, - wrappedTbtcMint, - tbtcMint, - recipientWrappedToken: wrappedTbtcToken.address, - recipientToken: recipientToken.address, - recipient: payer.publicKey, - tbtcConfig, - minterInfo, - tbtcProgram: tbtcProgram.programId, - }) - .signers(tbtc.maybeAuthorityAnd(payer, [])) - .rpc(); - - await tbtc.checkState(tbtcProgram, authority, 2, 2, 2000); - try { - await program.methods - .depositWormholeTbtc(new anchor.BN(50000)) - .accounts({ - custodian, - wrappedTbtcToken: gatewayWrappedTbtcToken, - wrappedTbtcMint, - tbtcMint, - recipientWrappedToken: wrappedTbtcToken.address, - recipientToken: recipientToken.address, - recipient: payer.publicKey, - tbtcConfig, - minterInfo, - tbtcProgram: tbtcProgram.programId, - }) - .signers(tbtc.maybeAuthorityAnd(payer, [])) - .rpc(); + await depositWormholeTbtc( + program, + tbtcProgram, + 50000, + wrappedTbtcToken.address, + recipientToken.address, + payer, + minterInfo + ); chai.assert(false, "should've failed but didn't"); } catch (_err) { expect(_err).to.be.instanceOf(AnchorError); @@ -228,24 +244,74 @@ describe("wormhole-gateway", () => { expect(err.program.equals(program.programId)).is.true; } }); -}); -async function mockSignAndPostVaa(connection: web3.Connection, payer: web3.Keypair, published: Buffer) { - const guardians = new mock.MockGuardians( - GUARDIAN_SET_INDEX, - ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"] - ); + it('won\'t deposit wrapped tokens with mismatched token types', async () => { + const minterInfo = tbtc.getMinterPDA(tbtcProgram, custodian)[0]; + const payer = await generatePayer(connection, authority.payer); + const wrappedTbtcToken = await bridgeToSolana(BigInt("100000000000"), connection, payer, ethereumTokenBridge); + const recipientToken = await getOrCreateTokenAccount(connection, payer, tbtcMint, payer.publicKey); - // Add guardian signature. - const signedVaa = guardians.addSignatures(published, [0]); + try { + await depositWormholeTbtc( + program, + tbtcProgram, + 500, + recipientToken.address, + recipientToken.address, + payer, + minterInfo + ); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('ConstraintTokenMint'); + expect(err.program.equals(program.programId)).is.true; + } + try { + await depositWormholeTbtc( + program, + tbtcProgram, + 500, + wrappedTbtcToken.address, + wrappedTbtcToken.address, + payer, + minterInfo + ); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('ConstraintTokenMint'); + expect(err.program.equals(program.programId)).is.true; + } + }); - // Verify and post VAA. - await postVaaSolana(connection, - new NodeWallet(payer).signTransaction, - SOLANA_CORE_BRIDGE_ADDRESS, - payer.publicKey, - signedVaa - ); + it('won\'t deposit wrapped tokens to wrong address', async () => { + const minterInfo = tbtc.getMinterPDA(tbtcProgram, custodian)[0]; + const payer = await generatePayer(connection, authority.payer); + const payer2 = await generatePayer(connection, authority.payer); + const wrappedTbtcToken = await bridgeToSolana(BigInt("100000000000"), connection, payer, ethereumTokenBridge); + const recipientToken = await getOrCreateTokenAccount(connection, payer, tbtcMint, payer.publicKey); + const wrappedTbtcToken2 = await bridgeToSolana(BigInt("100"), connection, payer2, ethereumTokenBridge); + const recipient2Token = await getOrCreateTokenAccount(connection, payer, tbtcMint, payer2.publicKey); - return signedVaa; -} + try { + await depositWormholeTbtc( + program, + tbtcProgram, + 50000, + wrappedTbtcToken.address, + recipient2Token.address, + payer, + minterInfo + ); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('ConstraintTokenOwner'); + expect(err.program.equals(program.programId)).is.true; + } + }); +}); diff --git a/cross-chain/solana/tests/helpers/tbtcHelpers.ts b/cross-chain/solana/tests/helpers/tbtcHelpers.ts index a0918c1d1..49ef518ed 100644 --- a/cross-chain/solana/tests/helpers/tbtcHelpers.ts +++ b/cross-chain/solana/tests/helpers/tbtcHelpers.ts @@ -92,23 +92,23 @@ export async function checkState( const [config,] = getConfigPDA(program); let configState = await program.account.config.fetch(config); - expect(configState.authority).to.eql(expectedAuthority.publicKey); - expect(configState.numMinters).to.equal(expectedMinters); - expect(configState.numGuardians).to.equal(expectedGuardians); - + expect(configState.authority).to.eql(expectedAuthority.publicKey, "wrong authority"); + expect(configState.numMinters).to.equal(expectedMinters, "wrong number of minters in config"); + expect(configState.numGuardians).to.equal(expectedGuardians, "wrong number of guardians in config"); + let tbtcMint = configState.mint; let mintState = await spl.getMint(program.provider.connection, tbtcMint); - expect(mintState.supply).to.equal(BigInt(expectedTokensSupply)); + expect(mintState.supply).to.equal(BigInt(expectedTokensSupply), "wrong amount of tbtc tokens minted"); const [guardians,] = getGuardiansPDA(program); let guardiansState = await program.account.guardians.fetch(guardians); - expect(guardiansState.keys).has.length(expectedGuardians); + expect(guardiansState.keys).has.length(expectedGuardians, "wrong length of guardians"); const [minters,] = getMintersPDA(program); let mintersState = await program.account.minters.fetch(minters); - expect(mintersState.keys).has.length(expectedMinters); + expect(mintersState.keys).has.length(expectedMinters, "wrong length of minters"); } export async function addMinter( diff --git a/cross-chain/solana/tests/helpers/wormholeGatewayHelpers.ts b/cross-chain/solana/tests/helpers/wormholeGatewayHelpers.ts index 90d2ee31d..f9033d310 100644 --- a/cross-chain/solana/tests/helpers/wormholeGatewayHelpers.ts +++ b/cross-chain/solana/tests/helpers/wormholeGatewayHelpers.ts @@ -1,8 +1,20 @@ import * as anchor from "@coral-xyz/anchor"; import { Program } from "@coral-xyz/anchor"; import * as web3 from '@solana/web3.js'; + +import { postVaaSolana } from "@certusone/wormhole-sdk"; +import * as mock from "@certusone/wormhole-sdk/lib/cjs/mock"; +import { NodeWallet } from "@certusone/wormhole-sdk/lib/cjs/solana"; + import { WormholeGateway } from "../../target/types/wormhole_gateway"; +const SOLANA_CORE_BRIDGE_ADDRESS = "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth"; +const SOLANA_TOKEN_BRIDGE_ADDRESS = "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb"; +const ETHEREUM_TOKEN_BRIDGE_ADDRESS = "0x3ee18B2214AFF97000D974cf647E7C347E8fa585"; +const ETHEREUM_TBTC_ADDRESS = "0x18084fbA666a33d37592fA2633fD49a74DD93a88"; + +const GUARDIAN_SET_INDEX = 3; + export function getCustodianPDA( program: Program, ): [anchor.web3.PublicKey, number] { @@ -60,6 +72,26 @@ export function getTokenBridgeRedeemerPDA( ); } +export async function mockSignAndPostVaa(connection: web3.Connection, payer: web3.Keypair, published: Buffer) { + const guardians = new mock.MockGuardians( + GUARDIAN_SET_INDEX, + ["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"] + ); + + // Add guardian signature. + const signedVaa = guardians.addSignatures(published, [0]); + + // Verify and post VAA. + await postVaaSolana(connection, + new NodeWallet(payer).signTransaction, + SOLANA_CORE_BRIDGE_ADDRESS, + payer.publicKey, + signedVaa + ); + + return signedVaa; +} + function toBytesLE(x): Buffer { const buf = Buffer.alloc(2); buf.writeUint16LE(x); From 8ed32b7fae233e9544c36b600e80346dd66efa5d Mon Sep 17 00:00:00 2001 From: Promethea Raschke Date: Thu, 3 Aug 2023 16:19:00 +0100 Subject: [PATCH 2/3] Improve deposit tests --- .../solana/tests/02__wormholeGateway.ts | 34 +++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/cross-chain/solana/tests/02__wormholeGateway.ts b/cross-chain/solana/tests/02__wormholeGateway.ts index 09bc6e025..6d9ce10ad 100644 --- a/cross-chain/solana/tests/02__wormholeGateway.ts +++ b/cross-chain/solana/tests/02__wormholeGateway.ts @@ -220,7 +220,7 @@ describe("wormhole-gateway", () => { await tbtc.checkState(tbtcProgram, authority, 2, 2, 2000); }); - it('won\'t deposit wrapped tokens over the minting limit', async () => { + it('- won\'t deposit wrapped tokens over the minting limit', async () => { const minterInfo = tbtc.getMinterPDA(tbtcProgram, custodian)[0]; const payer = await generatePayer(connection, authority.payer); const wrappedTbtcToken = await bridgeToSolana(BigInt("100000000000"), connection, payer, ethereumTokenBridge); @@ -245,7 +245,7 @@ describe("wormhole-gateway", () => { } }); - it('won\'t deposit wrapped tokens with mismatched token types', async () => { + it('- won\'t deposit wrapped tokens with mismatched token types', async () => { const minterInfo = tbtc.getMinterPDA(tbtcProgram, custodian)[0]; const payer = await generatePayer(connection, authority.payer); const wrappedTbtcToken = await bridgeToSolana(BigInt("100000000000"), connection, payer, ethereumTokenBridge); @@ -287,7 +287,7 @@ describe("wormhole-gateway", () => { } }); - it('won\'t deposit wrapped tokens to wrong address', async () => { + it('- won\'t deposit wrapped tokens to wrong owner', async () => { const minterInfo = tbtc.getMinterPDA(tbtcProgram, custodian)[0]; const payer = await generatePayer(connection, authority.payer); const payer2 = await generatePayer(connection, authority.payer); @@ -314,4 +314,32 @@ describe("wormhole-gateway", () => { expect(err.program.equals(program.programId)).is.true; } }); + + it('- won\'t deposit wrapped tokens from wrong owner', async () => { + const minterInfo = tbtc.getMinterPDA(tbtcProgram, custodian)[0]; + const payer = await generatePayer(connection, authority.payer); + const payer2 = await generatePayer(connection, authority.payer); + const wrappedTbtcToken = await bridgeToSolana(BigInt("100000000000"), connection, payer, ethereumTokenBridge); + const recipientToken = await getOrCreateTokenAccount(connection, payer, tbtcMint, payer.publicKey); + const wrappedTbtcToken2 = await bridgeToSolana(BigInt("100"), connection, payer2, ethereumTokenBridge); + const recipient2Token = await getOrCreateTokenAccount(connection, payer, tbtcMint, payer2.publicKey); + + try { + await depositWormholeTbtc( + program, + tbtcProgram, + 50000, + wrappedTbtcToken2.address, + recipientToken.address, + payer, + minterInfo + ); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('ConstraintTokenOwner'); + expect(err.program.equals(program.programId)).is.true; + } + }); }); From 96a9ab98939ddb59412c5fd3ea0ea7621081be07 Mon Sep 17 00:00:00 2001 From: Promethea Raschke Date: Thu, 3 Aug 2023 16:22:46 +0100 Subject: [PATCH 3/3] Add unhappy path for minting limit --- .../solana/tests/02__wormholeGateway.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/cross-chain/solana/tests/02__wormholeGateway.ts b/cross-chain/solana/tests/02__wormholeGateway.ts index 6d9ce10ad..671642e5b 100644 --- a/cross-chain/solana/tests/02__wormholeGateway.ts +++ b/cross-chain/solana/tests/02__wormholeGateway.ts @@ -200,6 +200,25 @@ describe("wormhole-gateway", () => { await checkCustodianState(program, authority, 20000); }); + it('- won\'t let non-authority update minting limit', async () => { + try { + await program.methods + .updateMintingLimit(new anchor.BN(20000)) + .accounts({ + custodian, + authority: impostorKeys.publicKey + }) + .signers([impostorKeys]) + .rpc(); + chai.assert(false, "should've failed but didn't"); + } catch (_err) { + expect(_err).to.be.instanceOf(AnchorError); + const err: AnchorError = _err; + expect(err.error.errorCode.code).to.equal('IsNotAuthority'); + expect(err.program.equals(program.programId)).is.true; + } + }); + it('deposit wrapped tokens', async () => { // Set up new wallet const payer = await generatePayer(connection, authority.payer);