jest.mock('ethers', () => { return { Contract: jest.fn().mockImplementation((address, abi, signer) => ({ address, abi, signer, totalFees0: jest.fn().mockResolvedValue(0n), })), }; }); jest.mock('../../src/helpers/AbiManager', () => { return { AbiManager: jest.fn().mockImplementation(() => ({ getPoolAbi: jest.fn().mockReturnValue(['pool']), getFactoryAbi: jest.fn().mockReturnValue(['factory']), getQuoterV2Abi: jest.fn().mockReturnValue(['quoter']), getVaultAbi: jest.fn().mockReturnValue(['vault']), getSteerPeripheryAbi: jest.fn().mockReturnValue(['periphery']), })), }; }); jest.mock('../../src/helpers/ProtocolDetector', () => { return { ProtocolDetector: jest.fn().mockImplementation(() => ({})), }; }); jest.mock('../../src/helpers/QuoterFactory', () => { return { QuoterFactory: jest.fn().mockImplementation(() => ({ createQuoterV2: jest.fn().mockReturnValue({ address: '0xquoter' }), })), }; }); import { ContractFactory } from '../../src/helpers/ContractFactory'; describe('ContractFactory behavior', () => { it('creates pool and factory contracts with ABIs', () => { const factory = new ContractFactory({} as any); const pool = factory.createPoolContract('0xpool', 'beacon'); const factoryContract = factory.createFactoryContract( '0xfactory', 'beacon', ); expect(pool.abi).toEqual(['pool']); expect(factoryContract.abi).toEqual(['factory']); }); it('throws when networkConfig not provided', () => { const factory = new ContractFactory({} as any); expect(() => factory.createQuoterContract('beacon')).toThrow( 'QuoterFactory not initialized', ); }); it('throws when missing beacon name', () => { const factory = new ContractFactory({} as any); expect(() => factory.createQuoterContract(undefined)).toThrow( 'beaconName is required', ); }); it('throws when dynamic resolution without networkConfig', () => { const factory = new ContractFactory({} as any); expect(() => factory.createQuoterContract('beacon')).toThrow( 'QuoterFactory not initialized', ); }); it('uses QuoterFactory when networkConfig provided', () => { const factory = new ContractFactory( {} as any, undefined, undefined, {} as any, ); const quoter = factory.createQuoterContract('beacon'); expect(quoter.address).toBe('0xquoter'); }); it('creates vault and periphery contracts', () => { const factory = new ContractFactory({} as any); const vault = factory.createVaultContract('0xvault', 'beacon'); const periphery = factory.createSteerPeripheryContract('0xperiphery'); expect(vault.abi).toEqual(['vault']); expect(periphery.abi).toEqual(['periphery']); }); it('detects upgrades based on totalFees0', async () => { const factory = new ContractFactory({} as any); await expect(factory.detectVaultUpgrade('0xvault', 'beacon')).resolves.toBe( true, ); const ethers = require('ethers'); ethers.Contract.mockImplementationOnce(() => ({ totalFees0: jest.fn().mockRejectedValue(new Error('fail')), })); await expect(factory.detectVaultUpgrade('0xvault', 'beacon')).resolves.toBe( false, ); }); it('checks multi position vault naming', () => { const factory = new ContractFactory({} as any); expect(factory.isMultiPositionVault('MultiVault')).toBe(true); expect(factory.isMultiPositionVault('AerodromeVault')).toBe(true); expect(factory.isMultiPositionVault('RegularVault')).toBe(false); }); });