@@ -46,24 +46,29 @@ import {
4646const ALCHEMY_GAS_SPONSOR_API_KEY = getEnv ( 'ALCHEMY_GAS_SPONSOR_API_KEY' ) ;
4747const ALCHEMY_GAS_SPONSOR_POLICY_ID = getEnv ( 'ALCHEMY_GAS_SPONSOR_POLICY_ID' ) ;
4848
49- // const SWAP_AMOUNT = 80;
50- // const SWAP_TOKEN_IN_ADDRESS = '0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed'; // DEGEN
51- // const SWAP_TOKEN_IN_DECIMALS = 18;
49+ const SWAP_AMOUNT = 80 ;
50+ const SWAP_TOKEN_IN_ADDRESS = '0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed' ; // DEGEN
51+ const SWAP_TOKEN_IN_DECIMALS = 18 ;
5252
5353// const SWAP_AMOUNT = 0.0003;
5454// const SWAP_TOKEN_IN_ADDRESS = '0x4200000000000000000000000000000000000006'; // WETH
5555// const SWAP_TOKEN_IN_DECIMALS = 18;
5656
57- const SWAP_AMOUNT = 0.1 ;
58- const SWAP_TOKEN_IN_ADDRESS = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' ; // USDC
59- const SWAP_TOKEN_IN_DECIMALS = 6 ;
57+ // const SWAP_AMOUNT = 0.1;
58+ // const SWAP_TOKEN_IN_ADDRESS = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'; // USDC
59+ // const SWAP_TOKEN_IN_DECIMALS = 6;
60+
61+ const EXPECTED_SWAP_AMOUNT = ethers . utils . formatUnits (
62+ ethers . utils . parseUnits ( SWAP_AMOUNT . toString ( ) , SWAP_TOKEN_IN_DECIMALS ) ,
63+ SWAP_TOKEN_IN_DECIMALS ,
64+ ) ;
6065
61- // const SWAP_TOKEN_OUT_ADDRESS = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'; // USDC
62- // const SWAP_TOKEN_OUT_DECIMALS = 6;
66+ const SWAP_TOKEN_OUT_ADDRESS = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' ; // USDC
67+ const SWAP_TOKEN_OUT_DECIMALS = 6 ;
6368// const SWAP_TOKEN_OUT_ADDRESS = '0x4200000000000000000000000000000000000006'; // WETH
6469// const SWAP_TOKEN_OUT_DECIMALS = 18;
65- const SWAP_TOKEN_OUT_ADDRESS = '0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed' ; // DEGEN
66- const SWAP_TOKEN_OUT_DECIMALS = 18 ;
70+ // const SWAP_TOKEN_OUT_ADDRESS = '0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed'; // DEGEN
71+ // const SWAP_TOKEN_OUT_DECIMALS = 18;
6772
6873const RPC_URL = BASE_RPC_URL ;
6974const CHAIN_ID = 8453 ;
@@ -359,6 +364,41 @@ describe('Uniswap Swap Ability E2E Tests', () => {
359364 } ) ;
360365
361366 describe ( 'Precheck and Execute without Alchemy Gas Sponsorship' , ( ) => {
367+ it ( 'should fail precheck because of invalid ability action' , async ( ) => {
368+ const signedUniswapQuote = await validateSignedUniswapQuoteIsDefined ( SIGNED_UNISWAP_QUOTE ) ;
369+ const uniswapSwapAbilityClient = getUniswapSwapAbilityClient ( ) ;
370+
371+ // Try to precheck with the malicious quote
372+ const precheckResult = await uniswapSwapAbilityClient . precheck (
373+ {
374+ // @ts -expect-error - invalid ability action
375+ action : 'invalid' ,
376+ rpcUrlForUniswap : RPC_URL ,
377+ signedUniswapQuote : {
378+ quote : signedUniswapQuote . quote ,
379+ signature : signedUniswapQuote . signature ,
380+ } ,
381+ alchemyGasSponsor : false ,
382+ } ,
383+ {
384+ delegatorPkpEthAddress : TEST_CONFIG . userPkp ! . ethAddress ! ,
385+ } ,
386+ ) ;
387+ console . log (
388+ '[should fail precheck because of invalid ability action]' ,
389+ util . inspect ( precheckResult , { depth : 10 } ) ,
390+ ) ;
391+
392+ // Precheck should fail with recipient validation error
393+ expect ( precheckResult ) . toBeDefined ( ) ;
394+ expect ( precheckResult . success ) . toBe ( false ) ;
395+
396+ if ( precheckResult . success === false ) {
397+ expect ( precheckResult . runtimeError ) . toContain ( 'Invalid precheck parameters.' ) ;
398+ expect ( precheckResult . schemaValidationError ) . toBeTruthy ( ) ;
399+ }
400+ } ) ;
401+
362402 it ( 'should fail precheck because of insufficient tokenIn allowance' , async ( ) => {
363403 const signedUniswapQuote = await validateSignedUniswapQuoteIsDefined ( SIGNED_UNISWAP_QUOTE ) ;
364404 const uniswapSwapAbilityClient = getUniswapSwapAbilityClient ( ) ;
@@ -394,10 +434,38 @@ describe('Uniswap Swap Ability E2E Tests', () => {
394434 ) ;
395435 expect ( innerResult . spenderAddress ) . toBe ( signedUniswapQuote . quote . to ) ;
396436 expect ( innerResult . tokenAddress ) . toBe ( SWAP_TOKEN_IN_ADDRESS ) ;
397- expect ( innerResult . requiredAllowance ) . toBe (
398- ethers . utils . parseUnits ( SWAP_AMOUNT . toString ( ) , SWAP_TOKEN_IN_DECIMALS ) . toString ( ) ,
437+ expect ( innerResult . requiredAllowance ) . toBe ( EXPECTED_SWAP_AMOUNT ) ;
438+ expect ( innerResult . currentAllowance ) . toBe ( '0.0' ) ;
439+ } ) ;
440+
441+ it ( 'should fail execute because of invalid ability action' , async ( ) => {
442+ const signedUniswapQuote = await validateSignedUniswapQuoteIsDefined ( SIGNED_UNISWAP_QUOTE ) ;
443+ const uniswapSwapAbilityClient = getUniswapSwapAbilityClient ( ) ;
444+
445+ const executeResult = await uniswapSwapAbilityClient . execute (
446+ {
447+ // @ts -expect-error - invalid ability action
448+ action : 'invalid' ,
449+ rpcUrlForUniswap : RPC_URL ,
450+ signedUniswapQuote : signedUniswapQuote ,
451+ alchemyGasSponsor : false ,
452+ } ,
453+ {
454+ delegatorPkpEthAddress : TEST_CONFIG . userPkp ! . ethAddress ! ,
455+ } ,
399456 ) ;
400- expect ( innerResult . currentAllowance ) . toBe ( '0' ) ;
457+ console . log (
458+ '[should fail execute because of invalid ability action]' ,
459+ util . inspect ( executeResult , { depth : 10 } ) ,
460+ ) ;
461+
462+ expect ( executeResult ) . toBeDefined ( ) ;
463+ expect ( executeResult . success ) . toBe ( false ) ;
464+
465+ if ( executeResult . success === false ) {
466+ expect ( executeResult . runtimeError ) . toContain ( 'Invalid execute parameters.' ) ;
467+ expect ( executeResult . schemaValidationError ) . toBeTruthy ( ) ;
468+ }
401469 } ) ;
402470
403471 it ( 'should make a new ERC20 approval transaction for the Uniswap router' , async ( ) => {
@@ -466,10 +534,8 @@ describe('Uniswap Swap Ability E2E Tests', () => {
466534
467535 expect ( executeResult . result ) . toBeDefined ( ) ;
468536 expect ( executeResult . result . approvalTxHash ) . toBeUndefined ( ) ;
469- expect ( executeResult . result . currentAllowance ) . toBeDefined ( ) ;
470- expect ( BigInt ( executeResult . result . currentAllowance ! ) ) . toBeGreaterThanOrEqual (
471- BigInt ( ethers . utils . parseUnits ( SWAP_AMOUNT . toString ( ) , SWAP_TOKEN_IN_DECIMALS ) . toString ( ) ) ,
472- ) ;
537+ expect ( executeResult . result . currentAllowance ! ) . toBe ( EXPECTED_SWAP_AMOUNT ) ;
538+ expect ( executeResult . result . requiredAllowance ! ) . toBe ( EXPECTED_SWAP_AMOUNT ) ;
473539 } ) ;
474540
475541 it ( 'should successfully run precheck on the Uniswap Swap Ability' , async ( ) => {
@@ -516,12 +582,23 @@ describe('Uniswap Swap Ability E2E Tests', () => {
516582 // Verify the result is properly populated
517583 expect ( precheckResult . result ) . toBeDefined ( ) ;
518584 expect ( precheckResult . result ! . nativeTokenBalance ) . toBeDefined ( ) ;
519- expect ( BigInt ( precheckResult . result ! . nativeTokenBalance as string ) ) . toBeGreaterThan ( 0n ) ;
585+ expect (
586+ ethers . utils . parseEther ( precheckResult . result ! . nativeTokenBalance as string ) . toBigInt ( ) ,
587+ ) . toBeGreaterThan ( 0n ) ;
588+
520589 expect ( precheckResult . result ! . tokenInAddress ) . toBe ( SWAP_TOKEN_IN_ADDRESS ) ;
521590 expect ( precheckResult . result ! . tokenInBalance ) . toBeDefined ( ) ;
522- expect ( BigInt ( precheckResult . result ! . tokenInBalance as string ) ) . toBeGreaterThan ( 0n ) ;
523- expect ( BigInt ( precheckResult . result ! . currentTokenInAllowanceForSpender ) ) . toBeGreaterThan ( 0n ) ;
591+ expect (
592+ ethers . utils
593+ . parseUnits ( precheckResult . result ! . tokenInBalance as string , SWAP_TOKEN_IN_DECIMALS )
594+ . toBigInt ( ) ,
595+ ) . toBeGreaterThan ( 0n ) ;
596+
597+ expect ( precheckResult . result ! . currentTokenInAllowanceForSpender as string ) . toBe (
598+ EXPECTED_SWAP_AMOUNT ,
599+ ) ;
524600 expect ( precheckResult . result ! . spenderAddress ) . toBe ( signedUniswapQuote . quote . to ) ;
601+ expect ( precheckResult . result ! . requiredTokenInAllowance ! ) . toBe ( EXPECTED_SWAP_AMOUNT ) ;
525602 } ) ;
526603
527604 it ( 'should execute the Uniswap Swap Ability with the Agent Wallet PKP' , async ( ) => {
@@ -619,10 +696,8 @@ describe('Uniswap Swap Ability E2E Tests', () => {
619696 ) ;
620697 expect ( innerResult . spenderAddress ) . toBe ( signedUniswapQuote . quote . to ) ;
621698 expect ( innerResult . tokenAddress ) . toBe ( SWAP_TOKEN_IN_ADDRESS ) ;
622- expect ( innerResult . requiredAllowance ) . toBe (
623- ethers . utils . parseUnits ( SWAP_AMOUNT . toString ( ) , SWAP_TOKEN_IN_DECIMALS ) . toString ( ) ,
624- ) ;
625- expect ( innerResult . currentAllowance ) . toBe ( '0' ) ;
699+ expect ( innerResult . requiredAllowance ) . toBe ( EXPECTED_SWAP_AMOUNT ) ;
700+ expect ( innerResult . currentAllowance ) . toBe ( '0.0' ) ;
626701 } ) ;
627702
628703 it ( 'should make a new ERC20 approval transaction for the Uniswap router' , async ( ) => {
@@ -704,10 +779,8 @@ describe('Uniswap Swap Ability E2E Tests', () => {
704779
705780 expect ( executeResult . result ) . toBeDefined ( ) ;
706781 expect ( executeResult . result . approvalTxHash ) . toBeUndefined ( ) ;
707- expect ( executeResult . result . currentAllowance ) . toBeDefined ( ) ;
708- expect ( BigInt ( executeResult . result . currentAllowance ! ) ) . toBeGreaterThanOrEqual (
709- BigInt ( ethers . utils . parseUnits ( SWAP_AMOUNT . toString ( ) , SWAP_TOKEN_IN_DECIMALS ) . toString ( ) ) ,
710- ) ;
782+ expect ( executeResult . result . currentAllowance ! ) . toBe ( EXPECTED_SWAP_AMOUNT ) ;
783+ expect ( executeResult . result . requiredAllowance ! ) . toBe ( EXPECTED_SWAP_AMOUNT ) ;
711784 } ) ;
712785
713786 it ( 'should successfully run precheck on the Uniswap Swap Ability' , async ( ) => {
@@ -757,10 +830,16 @@ describe('Uniswap Swap Ability E2E Tests', () => {
757830 expect ( precheckResult . result ) . toBeDefined ( ) ;
758831 expect ( precheckResult . result ! . nativeTokenBalance ) . toBeUndefined ( ) ;
759832 expect ( precheckResult . result ! . tokenInAddress ) . toBe ( SWAP_TOKEN_IN_ADDRESS ) ;
760- expect ( precheckResult . result ! . tokenInBalance ) . toBeDefined ( ) ;
761- expect ( BigInt ( precheckResult . result ! . tokenInBalance as string ) ) . toBeGreaterThan ( 0n ) ;
762- expect ( BigInt ( precheckResult . result ! . currentTokenInAllowanceForSpender ) ) . toBeGreaterThan ( 0n ) ;
833+ expect (
834+ ethers . utils
835+ . parseUnits ( precheckResult . result ! . tokenInBalance as string , SWAP_TOKEN_IN_DECIMALS )
836+ . toBigInt ( ) ,
837+ ) . toBeGreaterThan ( 0n ) ;
838+ expect ( precheckResult . result ! . currentTokenInAllowanceForSpender as string ) . toBe (
839+ EXPECTED_SWAP_AMOUNT ,
840+ ) ;
763841 expect ( precheckResult . result ! . spenderAddress ) . toBe ( signedUniswapQuote . quote . to ) ;
842+ expect ( precheckResult . result ! . requiredTokenInAllowance ! ) . toBe ( EXPECTED_SWAP_AMOUNT ) ;
764843 } ) ;
765844
766845 it ( 'should execute the Uniswap Swap Ability with the Agent Wallet PKP' , async ( ) => {
0 commit comments