@@ -1009,6 +1009,80 @@ describe("Gateway", () => {
10091009 }
10101010 } ) ;
10111011
1012+ it ( "Calls execute and onCall reverts if signer is passed in remaining accounts" , async ( ) => {
1013+ await gatewayProgram . methods
1014+ . deposit ( new anchor . BN ( 1_000_000_000 ) , Array . from ( address ) )
1015+ . rpc ( ) ;
1016+
1017+ const randomWallet = anchor . web3 . Keypair . generate ( ) ;
1018+ const lastMessageData = "revert" ;
1019+ const data = Buffer . from ( lastMessageData , "utf-8" ) ;
1020+ let seeds = [ Buffer . from ( "connected" , "utf-8" ) ] ;
1021+ const [ connectedPdaAccount ] = anchor . web3 . PublicKey . findProgramAddressSync (
1022+ seeds ,
1023+ connectedProgram . programId
1024+ ) ;
1025+ const amount = new anchor . BN ( 500000000 ) ;
1026+
1027+ // signature
1028+ const pdaAccountData = await gatewayProgram . account . pda . fetch ( pdaAccount ) ;
1029+ const nonce = pdaAccountData . nonce ;
1030+ const buffer = Buffer . concat ( [
1031+ Buffer . from ( "ZETACHAIN" , "utf-8" ) ,
1032+ Buffer . from ( [ 0x05 ] ) ,
1033+ chain_id_bn . toArrayLike ( Buffer , "be" , 8 ) ,
1034+ nonce . toArrayLike ( Buffer , "be" , 8 ) ,
1035+ amount . toArrayLike ( Buffer , "be" , 8 ) ,
1036+ connectedProgram . programId . toBuffer ( ) ,
1037+ data ,
1038+ ] ) ;
1039+ const message_hash = keccak256 ( buffer ) ;
1040+ const signature = keyPair . sign ( message_hash , "hex" ) ;
1041+ const { r, s, recoveryParam } = signature ;
1042+ const signatureBuffer = Buffer . concat ( [
1043+ r . toArrayLike ( Buffer , "be" , 32 ) ,
1044+ s . toArrayLike ( Buffer , "be" , 32 ) ,
1045+ ] ) ;
1046+
1047+ try {
1048+ // call the `execute` function in the gateway program
1049+ await gatewayProgram . methods
1050+ . execute (
1051+ amount ,
1052+ Array . from ( address ) ,
1053+ data ,
1054+ Array . from ( signatureBuffer ) ,
1055+ Number ( recoveryParam ) ,
1056+ Array . from ( message_hash ) ,
1057+ nonce
1058+ )
1059+ . accountsPartial ( {
1060+ // mandatory predefined accounts
1061+ signer : wallet . publicKey ,
1062+ pda : pdaAccount ,
1063+ destinationProgram : connectedProgram . programId ,
1064+ destinationProgramPda : connectedPdaAccount ,
1065+ } )
1066+ . remainingAccounts ( [
1067+ // accounts coming from withdraw and call msg
1068+ { pubkey : wallet . publicKey , isSigner : true , isWritable : true } ,
1069+ { pubkey : connectedPdaAccount , isSigner : false , isWritable : true } ,
1070+ { pubkey : pdaAccount , isSigner : false , isWritable : false } ,
1071+ { pubkey : randomWallet . publicKey , isSigner : false , isWritable : true } ,
1072+ {
1073+ pubkey : anchor . web3 . SystemProgram . programId ,
1074+ isSigner : false ,
1075+ isWritable : false ,
1076+ } ,
1077+ ] )
1078+ . rpc ( ) ;
1079+ throw new Error ( "Expected error not thrown" ) ; // This line will make the test fail if no error is thrown
1080+ } catch ( err ) {
1081+ expect ( err ) . to . be . instanceof ( anchor . AnchorError ) ;
1082+ expect ( err . message ) . to . include ( "InvalidInstructionData" ) ;
1083+ }
1084+ } ) ;
1085+
10121086 it ( "Calls execute spl token and onCall" , async ( ) => {
10131087 await connectedSPLProgram . methods . initialize ( ) . rpc ( ) ;
10141088
@@ -1251,6 +1325,123 @@ describe("Gateway", () => {
12511325 }
12521326 } ) ;
12531327
1328+ it ( "Calls execute spl token and onCall reverts if signer is passed in remaining accounts" , async ( ) => {
1329+ const randomWallet = anchor . web3 . Keypair . generate ( ) ;
1330+ let randomWalletAta = await spl . getOrCreateAssociatedTokenAccount (
1331+ conn ,
1332+ wallet ,
1333+ mint . publicKey ,
1334+ randomWallet . publicKey ,
1335+ true
1336+ ) ;
1337+ const lastMessageData = "revert" ;
1338+ const data = Buffer . from ( lastMessageData , "utf-8" ) ;
1339+ let seeds = [ Buffer . from ( "connected" , "utf-8" ) ] ;
1340+ const [ connectedPdaAccount ] = anchor . web3 . PublicKey . findProgramAddressSync (
1341+ seeds ,
1342+ connectedSPLProgram . programId
1343+ ) ;
1344+ let pda_ata = await spl . getAssociatedTokenAddress (
1345+ mint . publicKey ,
1346+ pdaAccount ,
1347+ true
1348+ ) ;
1349+ const pdaAccountData = await gatewayProgram . account . pda . fetch ( pdaAccount ) ;
1350+ const amount = new anchor . BN ( 500_000 ) ;
1351+ const nonce = pdaAccountData . nonce ;
1352+
1353+ let destinationPdaAta = await spl . getOrCreateAssociatedTokenAccount (
1354+ conn ,
1355+ wallet ,
1356+ mint . publicKey ,
1357+ connectedPdaAccount ,
1358+ true
1359+ ) ;
1360+
1361+ const buffer = Buffer . concat ( [
1362+ Buffer . from ( "ZETACHAIN" , "utf-8" ) ,
1363+ Buffer . from ( [ 0x06 ] ) ,
1364+ chain_id_bn . toArrayLike ( Buffer , "be" , 8 ) ,
1365+ nonce . toArrayLike ( Buffer , "be" , 8 ) ,
1366+ amount . toArrayLike ( Buffer , "be" , 8 ) ,
1367+ mint . publicKey . toBuffer ( ) ,
1368+ destinationPdaAta . address . toBuffer ( ) ,
1369+ data ,
1370+ ] ) ;
1371+ const message_hash = keccak256 ( buffer ) ;
1372+ const signature = keyPair . sign ( message_hash , "hex" ) ;
1373+ const { r, s, recoveryParam } = signature ;
1374+ const signatureBuffer = Buffer . concat ( [
1375+ r . toArrayLike ( Buffer , "be" , 32 ) ,
1376+ s . toArrayLike ( Buffer , "be" , 32 ) ,
1377+ ] ) ;
1378+
1379+ try {
1380+ // call the `execute_spl_token` function in the gateway program
1381+ await gatewayProgram . methods
1382+ . executeSplToken (
1383+ usdcDecimals ,
1384+ amount ,
1385+ Array . from ( address ) ,
1386+ data ,
1387+ Array . from ( signatureBuffer ) ,
1388+ Number ( recoveryParam ) ,
1389+ Array . from ( message_hash ) ,
1390+ nonce
1391+ )
1392+ . accountsPartial ( {
1393+ // mandatory predefined accounts
1394+ signer : wallet . publicKey ,
1395+ pda : pdaAccount ,
1396+ pdaAta : pda_ata ,
1397+ mintAccount : mint . publicKey ,
1398+ destinationProgram : connectedSPLProgram . programId ,
1399+ destinationProgramPda : connectedPdaAccount ,
1400+ destinationProgramPdaAta : destinationPdaAta . address ,
1401+ tokenProgram : spl . TOKEN_PROGRAM_ID ,
1402+ associatedTokenProgram : spl . ASSOCIATED_TOKEN_PROGRAM_ID ,
1403+ systemProgram : SYSTEM_PROGRAM_ID ,
1404+ } )
1405+ . remainingAccounts ( [
1406+ // accounts coming from withdraw and call msg
1407+ { pubkey : wallet . publicKey , isSigner : true , isWritable : true } ,
1408+ { pubkey : connectedPdaAccount , isSigner : false , isWritable : true } ,
1409+ {
1410+ pubkey : destinationPdaAta . address ,
1411+ isSigner : false ,
1412+ isWritable : true ,
1413+ } ,
1414+ { pubkey : mint . publicKey , isSigner : false , isWritable : false } ,
1415+ { pubkey : pdaAccount , isSigner : false , isWritable : false } ,
1416+ {
1417+ pubkey : randomWallet . publicKey ,
1418+ isSigner : false ,
1419+ isWritable : false ,
1420+ } ,
1421+ {
1422+ pubkey : randomWalletAta . address ,
1423+ isSigner : false ,
1424+ isWritable : true ,
1425+ } ,
1426+ {
1427+ pubkey : spl . TOKEN_PROGRAM_ID ,
1428+ isSigner : false ,
1429+ isWritable : false ,
1430+ } ,
1431+ {
1432+ pubkey : SYSTEM_PROGRAM_ID ,
1433+ isSigner : false ,
1434+ isWritable : false ,
1435+ } ,
1436+ ] )
1437+ . rpc ( ) ;
1438+ throw new Error ( "Expected error not thrown" ) ; // This line will make the test fail if no error is thrown
1439+ } catch ( err ) {
1440+ expect ( err ) . to . be . instanceof ( anchor . AnchorError ) ;
1441+ expect ( err . message ) . to . include ( "InvalidInstructionData" ) ;
1442+ }
1443+ } ) ;
1444+
12541445 it ( "Calls execute spl token and onCall reverts if wrong msg hash" , async ( ) => {
12551446 const randomWallet = anchor . web3 . Keypair . generate ( ) ;
12561447 let randomWalletAta = await spl . getOrCreateAssociatedTokenAccount (
0 commit comments