it('should parse string', async () => {
            await fc.assert(
                fc.asyncProperty(endpointArbitrary, fc.string(), async (eid, message) => {
                    const errorParser = await createContractErrorParser({ contract, eid })
                    const parsedError = await errorParser(message)

                    expect(parsedError).toEqual(new UnknownError(`Unknown error: ${message}`))
                })
            )
        })


unknown

it('should parse an Error', async () => {
            await fc.assert(
                fc.asyncProperty(endpointArbitrary, fc.string(), async (eid, message) => {
                    const errorParser = await createContractErrorParser({ contract, eid })
                    const error = new Error(message)
                    const parsedError = await errorParser(error)

                    expect(parsedError).toEqual(new UnknownError(`Unknown error: ${error}`))
                })
            )
        })


it('should never reject', async () => {
            await fc.assert(
                fc.asyncProperty(endpointArbitrary, fc.anything(), async (eid, error) => {
                    const errorParser = await createContractErrorParser({ contract, eid })
                    const parsedError = await errorParser(error)

                    expect(parsedError).toBeInstanceOf(UnknownError)
                    expect(parsedError.reason).toBeUndefined()
                    expect(parsedError.message).toMatch(/Unknown error: /)
                })
            )
        })


it('should parse a custom an error with an argument coming from the contract itself', async () => {
            const errorParser = await createErrorParser()

            await fc.assert(
                fc.asyncProperty(fc.string(), async (arg) => {
                    const error = await assertFailed(contract.throwWithCustomErrorAndArgument(arg))
                    const parsedError = await errorParser(error)

                    expect(parsedError).toEqual(new CustomError('CustomErrorWithAnArgument', [arg]))
                })
            )
        })


it('should parse a custom an error with an argument coming from a nested contract', async () => {
            const errorParser = await createErrorParser()

            await fc.assert(
                fc.asyncProperty(fc.string(), async (arg) => {
                    const error = await assertFailed(contract.throwNestedWithCustomErrorAndArgument(arg))
                    const parsedError = await errorParser(error)

                    expect(parsedError).toEqual(new CustomError('NestedCustomErrorWithAnArgument', [arg]))
                })
            )
        })


it('should parse a custom an error with an different arguments defined in more contracts coming from the contract itself', async () => {
            const errorParser = await createErrorParser()

            await fc.assert(
                fc.asyncProperty(fc.string(), async (arg) => {
                    const error = await assertFailed(contract.throwWithCommonErrorAndArgument(arg))
                    const parsedError = await errorParser(error)

                    expect(parsedError).toEqual(new CustomError('CommonErrorWithAnArgument', [arg]))
                })
            )
        })


it('should parse a custom an error with different arguments defined in more contracts coming from a nested contract', async () => {
            const errorParser = await createErrorParser()

            await fc.assert(
                fc.asyncProperty(fc.integer({ min: 0 }), async (arg) => {
                    const error = await assertFailed(contract.throwNestedWithCommonErrorAndArgument(arg))
                    const parsedError = await errorParser(error)

                    expect(parsedError).toEqual(new CustomError('CommonErrorWithAnArgument', [BigNumber.from(arg)]))
                })
            )
        })


it('should never reject', async () => {
            const errorParser = await createErrorParser()

            await fc.assert(
                fc.asyncProperty(fc.anything(), async (error) => {
                    const parsedError = await errorParser(error)

                    expect(parsedError).toBeInstanceOf(UnknownError)
                    expect(parsedError.reason).toBeUndefined()
                    expect(parsedError.message).toMatch(/Unknown error: /)
                })
            )
        })


it('should succeed with a valid config', () => {
            fc.assert(
                fc.property(oappNodeConfigArbitrary, (config) => {
                    expect(OAppNodeConfigSchema.parse(config)).toEqual(config)
                })
            )
        })


it('should pass any additional properties through', () => {
            fc.assert(
                fc.property(
                    oappNodeConfigArbitrary,
                    fc.dictionary(fc.string(), fc.anything()),
                    (config, extraProperties) => {
                        const combined = Object.assign({}, extraProperties, config)

                        expect(combined).toMatchObject(OAppNodeConfigSchema.parse(combined))
                    }
                )
            )
        })


it('should call owner on the contract', async () => {
            await fc.assert(
                fc.asyncProperty(omniContractArbitrary, evmAddressArbitrary, async (omniContract, owner) => {
                    omniContract.contract.owner.mockResolvedValue(owner)

                    const sdk = new OApp(omniContract)
                    const ownable = Object.assign(sdk, OwnableMixin)

                    expect(await ownable.getOwner()).toBe(owner)
                    expect(omniContract.contract.owner).toHaveBeenCalledTimes(1)
                })
            )
        })


it('should return true if the owner addresses match', async () => {
            await fc.assert(
                fc.asyncProperty(omniContractArbitrary, evmAddressArbitrary, async (omniContract, owner) => {
                    omniContract.contract.owner.mockResolvedValue(owner)

                    const sdk = new OApp(omniContract)
                    const ownable = Object.assign(sdk, OwnableMixin)

                    expect(await ownable.hasOwner(owner)).toBeTruthy()
                })
            )
        })


it('should return false if the owner addresses do not match', async () => {
            await fc.assert(
                fc.asyncProperty(
                    omniContractArbitrary,
                    evmAddressArbitrary,
                    evmAddressArbitrary,
                    async (omniContract, owner, user) => {
                        fc.pre(!areBytes32Equal(owner, user))

                        omniContract.contract.owner.mockResolvedValue(owner)

                        const sdk = new OApp(omniContract)
                        const ownable = Object.assign(sdk, OwnableMixin)

                        expect(await ownable.hasOwner(user)).toBeFalsy()
                    }
                )
            )
        })


it('should encode data for a transferOwnership call', async () => {
            await fc.assert(
                fc.asyncProperty(omniContractArbitrary, evmAddressArbitrary, async (omniContract, owner) => {
                    const sdk = new OApp(omniContract)
                    const ownable = Object.assign(sdk, OwnableMixin)
                    const encodeFunctionData = omniContract.contract.interface.encodeFunctionData as jest.Mock

                    encodeFunctionData.mockClear()

                    await ownable.setOwner(owner)

                    expect(encodeFunctionData).toHaveBeenCalledTimes(1)
                    expect(encodeFunctionData).toHaveBeenCalledWith('transferOwnership', [owner])
                })
            )
        })


it('should call peers on the contract', async () => {
            await fc.assert(
                fc.asyncProperty(omniContractArbitrary, endpointArbitrary, async (omniContract, peerEid) => {
                    const sdk = new OApp(omniContract)

                    await sdk.getPeer(peerEid)

                    expect(omniContract.contract.peers).toHaveBeenCalledTimes(1)
                    expect(omniContract.contract.peers).toHaveBeenCalledWith(peerEid)
                })
            )
        })


it('should return undefined if peers() returns a zero address, null or undefined', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        evmEndpointArbitrary,
                        nullishAddressArbitrary,
                        async (omniContract, peerEid, peer) => {
                            omniContract.contract.peers.mockResolvedValue(peer)

                            const sdk = new OApp(omniContract)

                            await expect(sdk.getPeer(peerEid)).resolves.toBeUndefined()
                        }
                    )
                )
            })


it('should return an address if peers() returns a non-null bytes', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        evmEndpointArbitrary,
                        evmAddressArbitrary,
                        async (omniContract, peerEid, peer) => {
                            fc.pre(!isZero(peer))

                            omniContract.contract.peers.mockResolvedValue(peer)

                            const sdk = new OApp(omniContract)

                            await expect(sdk.getPeer(peerEid)).resolves.toBe(peer)
                        }
                    )
                )
            })


it('should return undefined if peers() returns a zero address, null or undefined', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        solanaEndpointArbitrary,
                        nullishAddressArbitrary,
                        async (omniContract, peerEid, peer) => {
                            omniContract.contract.peers.mockResolvedValue(peer)

                            const sdk = new OApp(omniContract)

                            await expect(sdk.getPeer(peerEid)).resolves.toBeUndefined()
                        }
                    )
                )
            })


it('should return an address if peers() returns a non-null bytes', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        evmEndpointArbitrary,
                        solanaEndpointArbitrary,
                        solanaAddressArbitrary,
                        async (omniContract, eid, peerEid, peer) => {
                            // For Solana we need to take the native address format and turn it into EVM bytes32
                            //
                            // We do this by normalizing the value into a UInt8Array,
                            // then denormalizing it using an EVM eid
                            const peerBytes = normalizePeer(peer, peerEid)
                            const peerHex = makeBytes32(peerBytes)

                            fc.pre(!isZero(peerHex))

                            omniContract.contract.peers.mockResolvedValue(peerHex)

                            const sdk = new OApp(omniContract)

                            await expect(sdk.getPeer(peerEid)).resolves.toBe(peer)
                        }
                    )
                )
            })


it('should return undefined if peers() returns a zero address, null or undefined', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        aptosEndpointArbitrary,
                        nullishAddressArbitrary,
                        async (omniContract, peerEid, peer) => {
                            omniContract.contract.peers.mockResolvedValue(peer)

                            const sdk = new OApp(omniContract)

                            await expect(sdk.getPeer(peerEid)).resolves.toBeUndefined()
                        }
                    )
                )
            })


it('should return an address if peers() returns a non-null bytes', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        aptosEndpointArbitrary,
                        aptosAddressArbitrary,
                        async (omniContract, peerEid, peer) => {
                            fc.pre(!isZero(peer))

                            omniContract.contract.peers.mockResolvedValue(peer)

                            const sdk = new OApp(omniContract)

                            await expect(sdk.getPeer(peerEid)).resolves.toBe(peer)
                        }
                    )
                )
            })


it('should return true if peers returns a zero address', async () => {
                    await fc.assert(
                        fc.asyncProperty(
                            omniContractArbitrary,
                            evmEndpointArbitrary,
                            nullishAddressArbitrary,
                            nullishAddressArbitrary,
                            async (omniContract, peerEid, peer, probePeer) => {
                                omniContract.contract.peers.mockResolvedValue(peer)

                                const sdk = new OApp(omniContract)

                                await expect(sdk.hasPeer(peerEid, probePeer)).resolves.toBe(true)
                            }
                        )
                    )
                })


it('should return false if peers returns a non-zero address', async () => {
                    await fc.assert(
                        fc.asyncProperty(
                            omniContractArbitrary,
                            evmEndpointArbitrary,
                            nullishAddressArbitrary,
                            evmAddressArbitrary,
                            async (omniContract, peerEid, peer, probePeer) => {
                                fc.pre(!isZero(probePeer))

                                omniContract.contract.peers.mockResolvedValue(peer)

                                const sdk = new OApp(omniContract)

                                await expect(sdk.hasPeer(peerEid, probePeer)).resolves.toBe(false)
                            }
                        )
                    )
                })


it('should return true if peers() returns a matching bytes32', async () => {
                    await fc.assert(
                        fc.asyncProperty(
                            omniContractArbitrary,
                            evmEndpointArbitrary,
                            evmAddressArbitrary,
                            async (omniContract, peerEid, peer) => {
                                omniContract.contract.peers.mockResolvedValue(makeBytes32(peer))

                                const sdk = new OApp(omniContract)

                                await expect(sdk.hasPeer(peerEid, peer)).resolves.toBe(true)
                                await expect(sdk.hasPeer(peerEid, makeBytes32(peer))).resolves.toBe(true)
                            }
                        )
                    )
                })


it('should return true if peers returns a zero address', async () => {
                    await fc.assert(
                        fc.asyncProperty(
                            omniContractArbitrary,
                            solanaEndpointArbitrary,
                            nullishAddressArbitrary,
                            async (omniContract, peerEid, peer) => {
                                omniContract.contract.peers.mockResolvedValue(peer)

                                const sdk = new OApp(omniContract)

                                await expect(sdk.hasPeer(peerEid, undefined)).resolves.toBe(true)
                            }
                        )
                    )
                })


it('should return false if peers returns a different value', async () => {
                    await fc.assert(
                        fc.asyncProperty(
                            omniContractArbitrary,
                            solanaEndpointArbitrary,
                            solanaAddressArbitrary,
                            solanaAddressArbitrary,
                            async (omniContract, peerEid, peer, probePeer) => {
                                fc.pre(
                                    !areBytes32Equal(normalizePeer(peer, peerEid), normalizePeer(probePeer, peerEid))
                                )

                                const peerHex = makeBytes32(normalizePeer(peer, peerEid))

                                omniContract.contract.peers.mockResolvedValue(peerHex)

                                const sdk = new OApp(omniContract)

                                await expect(sdk.hasPeer(peerEid, probePeer)).resolves.toBe(false)
                            }
                        )
                    )
                })


it('should return true if peers() returns a matching value', async () => {
                    await fc.assert(
                        fc.asyncProperty(
                            omniContractArbitrary,
                            solanaEndpointArbitrary,
                            solanaAddressArbitrary,
                            async (omniContract, peerEid, peer) => {
                                const peerHex = makeBytes32(normalizePeer(peer, peerEid))

                                omniContract.contract.peers.mockResolvedValue(peerHex)

                                const sdk = new OApp(omniContract)

                                await expect(sdk.hasPeer(peerEid, peer)).resolves.toBe(true)
                            }
                        )
                    )
                })


it('should return true if peers returns a zero address', async () => {
                    await fc.assert(
                        fc.asyncProperty(
                            omniContractArbitrary,
                            aptosEndpointArbitrary,
                            nullishAddressArbitrary,
                            nullishAddressArbitrary,
                            async (omniContract, peerEid, peer, probePeer) => {
                                omniContract.contract.peers.mockResolvedValue(peer)

                                const sdk = new OApp(omniContract)

                                await expect(sdk.hasPeer(peerEid, probePeer)).resolves.toBe(true)
                            }
                        )
                    )
                })


it('should return false if peers returns a non-zero address', async () => {
                    await fc.assert(
                        fc.asyncProperty(
                            omniContractArbitrary,
                            aptosEndpointArbitrary,
                            nullishAddressArbitrary,
                            aptosAddressArbitrary,
                            async (omniContract, peerEid, peer, probePeer) => {
                                fc.pre(!isZero(probePeer))

                                omniContract.contract.peers.mockResolvedValue(peer)

                                const sdk = new OApp(omniContract)

                                await expect(sdk.hasPeer(peerEid, probePeer)).resolves.toBe(false)
                            }
                        )
                    )
                })


it('should return true if peers() returns a matching bytes32', async () => {
                    await fc.assert(
                        fc.asyncProperty(
                            omniContractArbitrary,
                            aptosEndpointArbitrary,
                            aptosAddressArbitrary,
                            async (omniContract, peerEid, peer) => {
                                omniContract.contract.peers.mockResolvedValue(makeBytes32(peer))

                                const sdk = new OApp(omniContract)

                                await expect(sdk.hasPeer(peerEid, peer)).resolves.toBe(true)
                                await expect(sdk.hasPeer(peerEid, makeBytes32(peer))).resolves.toBe(true)
                            }
                        )
                    )
                })


it('should encode data for a setPeer call', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        evmEndpointArbitrary,
                        evmAddressArbitrary,
                        async (omniContract, peerEid, peerAddress) => {
                            const sdk = new OApp(omniContract)
                            const encodeFunctionData = omniContract.contract.interface.encodeFunctionData

                            ;(encodeFunctionData as jest.Mock).mockClear()

                            await sdk.setPeer(peerEid, peerAddress)

                            expect(encodeFunctionData).toHaveBeenCalledTimes(1)
                            expect(encodeFunctionData).toHaveBeenCalledWith('setPeer', [
                                peerEid,
                                makeBytes32(peerAddress),
                            ])
                        }
                    )
                )
            })


it('should return an OmniTransaction', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        evmEndpointArbitrary,
                        evmAddressArbitrary,
                        fc.string(),
                        async (omniContract, peerEid, peerAddress, data) => {
                            const encodeFunctionData = omniContract.contract.interface.encodeFunctionData as jest.Mock
                            encodeFunctionData.mockReturnValue(data)

                            const sdk = new OApp(omniContract)
                            const transaction = await sdk.setPeer(peerEid, peerAddress)

                            expect(transaction).toEqual({
                                data,
                                description: `Setting peer for eid ${peerEid} (${formatEid(peerEid)}) to address ${makeBytes32(peerAddress)}`,
                                point: {
                                    eid: omniContract.eid,
                                    address: omniContract.contract.address,
                                },
                            })
                        }
                    )
                )
            })


it('should encode data for a setPeer call', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        solanaEndpointArbitrary,
                        solanaAddressArbitrary,
                        async (omniContract, peerEid, peerAddress) => {
                            const sdk = new OApp(omniContract)
                            const encodeFunctionData = omniContract.contract.interface.encodeFunctionData

                            ;(encodeFunctionData as jest.Mock).mockClear()

                            await sdk.setPeer(peerEid, peerAddress)

                            expect(encodeFunctionData).toHaveBeenCalledTimes(1)
                            expect(encodeFunctionData).toHaveBeenCalledWith('setPeer', [
                                peerEid,
                                makeBytes32(normalizePeer(peerAddress, peerEid)),
                            ])
                        }
                    )
                )
            })


it('should return an OmniTransaction', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        solanaEndpointArbitrary,
                        solanaAddressArbitrary,
                        fc.string(),
                        async (omniContract, peerEid, peerAddress, data) => {
                            const encodeFunctionData = omniContract.contract.interface.encodeFunctionData as jest.Mock
                            encodeFunctionData.mockReturnValue(data)

                            const sdk = new OApp(omniContract)
                            const transaction = await sdk.setPeer(peerEid, peerAddress)

                            expect(transaction).toEqual({
                                data,
                                description: `Setting peer for eid ${peerEid} (${formatEid(peerEid)}) to address ${makeBytes32(normalizePeer(peerAddress, peerEid))}`,
                                point: {
                                    eid: omniContract.eid,
                                    address: omniContract.contract.address,
                                },
                            })
                        }
                    )
                )
            })


it('should encode data for a setPeer call', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        aptosEndpointArbitrary,
                        aptosAddressArbitrary,
                        async (omniContract, peerEid, peerAddress) => {
                            const sdk = new OApp(omniContract)
                            const encodeFunctionData = omniContract.contract.interface.encodeFunctionData

                            ;(encodeFunctionData as jest.Mock).mockClear()

                            await sdk.setPeer(peerEid, peerAddress)

                            expect(encodeFunctionData).toHaveBeenCalledTimes(1)
                            expect(encodeFunctionData).toHaveBeenCalledWith('setPeer', [
                                peerEid,
                                makeBytes32(peerAddress),
                            ])
                        }
                    )
                )
            })


it('should return an OmniTransaction', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        omniContractArbitrary,
                        aptosEndpointArbitrary,
                        aptosAddressArbitrary,
                        fc.string(),
                        async (omniContract, peerEid, peerAddress, data) => {
                            const encodeFunctionData = omniContract.contract.interface.encodeFunctionData as jest.Mock
                            encodeFunctionData.mockReturnValue(data)

                            const sdk = new OApp(omniContract)
                            const transaction = await sdk.setPeer(peerEid, peerAddress)

                            expect(transaction).toEqual({
                                data,
                                description: `Setting peer for eid ${peerEid} (${formatEid(peerEid)}) to address ${makeBytes32(peerAddress)}`,
                                point: {
                                    eid: omniContract.eid,
                                    address: omniContract.contract.address,
                                },
                            })
                        }
                    )
                )
            })


it('should reject if the call to endpoint() rejects', async () => {
            await fc.assert(
                fc.asyncProperty(omniContractArbitrary, async (omniContract) => {
                    omniContract.contract.endpoint.mockRejectedValue('No you did not')

                    const sdk = new OApp(omniContract)

                    await expect(sdk.getEndpointSDK()).rejects.toThrow(/Failed to get EndpointV2 address for OApp/)
                })
            )
        })


it('should reject if the call to endpoint() resolves with a zeroish address', async () => {
            await fc.assert(
                fc.asyncProperty(
                    omniContractArbitrary,
                    nullishAddressArbitrary,
                    async (omniContract, endpointAddress) => {
                        omniContract.contract.endpoint.mockResolvedValue(endpointAddress)

                        const sdk = new OApp(omniContract)

                        await expect(sdk.getEndpointSDK()).rejects.toThrow(
                            /EndpointV2 cannot be instantiated: EndpointV2 address has been set to a zero value for OApp/
                        )
                    }
                )
            )
        })


it('should return an EndpointV2 if the call to endpoint() resolves with a non-zeroish address', async () => {
            await fc.assert(
                fc.asyncProperty(omniContractArbitrary, evmAddressArbitrary, async (omniContract, endpointAddress) => {
                    fc.pre(!isZero(endpointAddress))

                    omniContract.contract.endpoint.mockResolvedValue(endpointAddress)

                    const sdk = new OApp(omniContract)
                    const endpoint = await sdk.getEndpointSDK()

                    expect(endpoint).toBeInstanceOf(EndpointV2)
                    expect(endpoint.point).toEqual({ eid: sdk.point.eid, address: endpointAddress })
                })
            )
        })


it('should return the contract name', async () => {
            await fc.assert(
                fc.asyncProperty(omniContractArbitrary, fc.string(), async (omniContract, name) => {
                    omniContract.contract.name.mockResolvedValue(name)

                    const sdk = new ERC20(omniContract)

                    await expect(sdk.getName()).resolves.toBe(name)

                    expect(omniContract.contract.name).toHaveBeenCalledTimes(1)
                })
            )
        })


it('should return the contract symbol', async () => {
            await fc.assert(
                fc.asyncProperty(omniContractArbitrary, fc.string(), async (omniContract, symbol) => {
                    omniContract.contract.symbol.mockResolvedValue(symbol)

                    const sdk = new ERC20(omniContract)

                    await expect(sdk.getSymbol()).resolves.toBe(symbol)

                    expect(omniContract.contract.symbol).toHaveBeenCalledTimes(1)
                })
            )
        })


it('should return the contract decimals', async () => {
            await fc.assert(
                fc.asyncProperty(omniContractArbitrary, fc.integer({ min: 1 }), async (omniContract, decimals) => {
                    omniContract.contract.decimals.mockResolvedValue(decimals)

                    const sdk = new ERC20(omniContract)

                    await expect(sdk.getDecimals()).resolves.toBe(decimals)

                    expect(omniContract.contract.decimals).toHaveBeenCalledTimes(1)
                })
            )
        })


it('should return the user balance', async () => {
            await fc.assert(
                fc.asyncProperty(
                    omniContractArbitrary,
                    evmAddressArbitrary,
                    fc.bigInt({ min: BigInt(0) }),
                    async (omniContract, user, balance) => {
                        omniContract.contract.balanceOf.mockResolvedValue(BigNumber.from(balance))

                        const sdk = new ERC20(omniContract)

                        await expect(sdk.getBalanceOf(user)).resolves.toBe(balance)

                        expect(omniContract.contract.balanceOf).toHaveBeenCalledTimes(1)
                        expect(omniContract.contract.balanceOf).toHaveBeenCalledWith(user)
                    }
                )
            )
        })


it('should return the user balance', async () => {
            await fc.assert(
                fc.asyncProperty(
                    omniContractArbitrary,
                    evmAddressArbitrary,
                    evmAddressArbitrary,
                    fc.bigInt({ min: BigInt(0) }),
                    async (omniContract, owner, spender, allowance) => {
                        omniContract.contract.allowance.mockResolvedValue(BigNumber.from(allowance))

                        const sdk = new ERC20(omniContract)

                        await expect(sdk.getAllowance(owner, spender)).resolves.toBe(allowance)

                        expect(omniContract.contract.allowance).toHaveBeenCalledTimes(1)
                        expect(omniContract.contract.allowance).toHaveBeenCalledWith(owner, spender)
                    }
                )
            )
        })


it('should not attempt to register libraries multiple times', async () => {
            await fc.assert(
                fc.asyncProperty(
                    pointArbitrary,
                    pointArbitrary,
                    pointArbitrary,
                    addressArbitrary,
                    async (pointA, pointB, pointC, libraryAddress) => {
                        fc.pre(!arePointsEqual(pointA, pointB))
                        fc.pre(!arePointsEqual(pointB, pointC))
                        fc.pre(!arePointsEqual(pointC, pointA))

                        const config: EndpointV2EdgeConfig = {
                            defaultReceiveLibrary: libraryAddress,
                            defaultSendLibrary: libraryAddress,
                        }

                        const graph: EndpointV2OmniGraph = {
                            contracts: [],
                            connections: [
                                {
                                    vector: { from: pointA, to: pointB },
                                    config,
                                },
                                {
                                    vector: { from: pointA, to: pointC },
                                    config,
                                },
                                {
                                    vector: { from: pointB, to: pointA },
                                    config,
                                },
                                {
                                    vector: { from: pointB, to: pointC },
                                    config,
                                },
                                {
                                    vector: { from: pointC, to: pointA },
                                    config,
                                },
                                {
                                    vector: { from: pointC, to: pointB },
                                    config,
                                },
                            ],
                        }

                        const createSdk = jest.fn((point: OmniPoint) => new MockSDK(point) as unknown as IEndpointV2)
                        const result = await configureEndpointV2RegisterLibraries(graph, createSdk)

                        // The result should not contain any duplicate library registrations
                        expect(result).toEqual([
                            { point: pointA, data: `0xREGISTERLIBRARY ${libraryAddress}` },
                            { point: pointB, data: `0xREGISTERLIBRARY ${libraryAddress}` },
                            { point: pointC, data: `0xREGISTERLIBRARY ${libraryAddress}` },
                        ])
                    }
                )
            )
        })


it('should sort requiredDVNs and optionalDVNs before encoding', async () => {
            fc.assert(
                fc.property(dvnsArbitrary, (dvns) => {
                    const sortedDvns = [...dvns].sort((a, b) => a.localeCompare(b))
                    const ulnConfigUnsorted: UlnReadUlnConfig = {
                        executor: AddressZero,
                        optionalDVNThreshold: 0,
                        optionalDVNs: dvns,
                        requiredDVNs: dvns,
                    }

                    const ulnConfigSorted: UlnReadUlnConfig = {
                        ...ulnConfigUnsorted,
                        optionalDVNs: sortedDvns,
                        requiredDVNs: sortedDvns,
                    }

                    const ulnConfigEncodedUnsorted = ulnSdk.encodeUlnConfig(ulnConfigUnsorted)
                    const ulnConfigEncodedSorted = ulnSdk.encodeUlnConfig(ulnConfigSorted)
                    expect(ulnConfigEncodedSorted).toBe(ulnConfigEncodedUnsorted)
                }),
                { numRuns: 20 }
            )
        })


it('should sort requiredDVNs and optionalDVNs', async () => {
            await fc.assert(
                fc.asyncProperty(channelIdArbitrary, dvnsArbitrary, async (eid, dvns) => {
                    const sortedDvns = [...dvns].sort((a, b) => a.localeCompare(b))
                    const ulnConfigUnsorted: UlnReadUlnConfig = {
                        executor: AddressZero,
                        optionalDVNThreshold: 0,
                        optionalDVNs: dvns,
                        requiredDVNs: dvns,
                    }

                    const ulnConfigSorted: UlnReadUlnConfig = {
                        ...ulnConfigUnsorted,
                        optionalDVNs: sortedDvns,
                        requiredDVNs: sortedDvns,
                    }

                    // Let's check that both the sorted and the unsorted config produce the same transaction
                    const transactionUnsorted = await ulnSdk.setDefaultUlnConfig(eid, ulnConfigUnsorted)
                    const transactionsSorted = await ulnSdk.setDefaultUlnConfig(eid, ulnConfigSorted)
                    expect(transactionUnsorted).toEqual(transactionsSorted)

                    // And let's check that the encoding call is correct and the DVNs are sorted
                    expect(transactionsSorted.data).toBe(
                        ulnSdk.contract.contract.interface.encodeFunctionData('setDefaultReadLibConfigs', [
                            [
                                {
                                    eid,
                                    config: {
                                        executor: AddressZero,
                                        optionalDVNThreshold: 0,
                                        optionalDVNs: sortedDvns.map(addChecksum),
                                        requiredDVNs: sortedDvns.map(addChecksum),
                                        requiredDVNCount: sortedDvns.length,
                                        optionalDVNCount: sortedDvns.length,
                                    },
                                },
                            ],
                        ])
                    )
                }),
                { numRuns: 20 }
            )
        })


it('should default the missing attributes', async () => {
            await fc.assert(
                fc.asyncProperty(channelIdArbitrary, dvnsArbitrary, async (eid, dvns) => {
                    const sortedDvns = [...dvns].sort((a, b) => a.localeCompare(b))
                    const ulnUserConfig: UlnReadUlnUserConfig = {
                        requiredDVNs: dvns,
                    }
                    const ulnConfig: UlnReadUlnConfig = {
                        requiredDVNs: dvns,
                        executor: AddressZero,
                        optionalDVNThreshold: 0,
                        optionalDVNs: [],
                    }

                    // Let's check that both the sorted and the unsorted config produce the same transaction
                    const transactionsWithDefaults = await ulnSdk.setDefaultUlnConfig(eid, ulnUserConfig)
                    const transactionsWithFullConfig = await ulnSdk.setDefaultUlnConfig(eid, ulnConfig)
                    expect(transactionsWithDefaults).toEqual(transactionsWithFullConfig)

                    // And let's check that the encoding call is correct and the DVNs are sorted
                    expect(transactionsWithDefaults.data).toBe(
                        ulnSdk.contract.contract.interface.encodeFunctionData('setDefaultReadLibConfigs', [
                            [
                                {
                                    eid,
                                    config: {
                                        executor: ulnConfig.executor,
                                        optionalDVNThreshold: ulnConfig.optionalDVNThreshold,
                                        optionalDVNs: ulnConfig.optionalDVNs,
                                        requiredDVNs: sortedDvns.map(addChecksum),
                                        requiredDVNCount: ulnConfig.requiredDVNs.length,
                                        optionalDVNCount: ulnConfig.optionalDVNs.length,
                                    },
                                },
                            ],
                        ])
                    )
                }),
                { numRuns: 20 }
            )
        })


it('should return true if the configs are identical', async () => {
            await fc.assert(
                fc.asyncProperty(
                    channelIdArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    async (channelId, oapp, ulnConfig) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(ulnSdk.hasAppUlnConfig(channelId, oapp, ulnConfig)).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return true if config has extra properties', async () => {
            await fc.assert(
                fc.asyncProperty(
                    channelIdArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    fc.object(),
                    async (channelId, oapp, ulnConfig, extra) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(channelId, oapp, {
                                ...extra,
                                ...ulnConfig,
                            })
                        ).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return true if configs with defaults are identical', async () => {
            await fc.assert(
                fc.asyncProperty(
                    channelIdArbitrary,
                    evmAddressArbitrary,
                    dvnsArbitrary,
                    async (channelId, oapp, dvns) => {
                        const ulnUserConfig: UlnReadUlnUserConfig = {
                            requiredDVNs: dvns,
                        }
                        const ulnConfig: UlnReadUlnConfig = {
                            requiredDVNs: dvns,
                            optionalDVNs: [],
                            optionalDVNThreshold: 0,
                            executor: AddressZero,
                        }

                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(ulnSdk.hasAppUlnConfig(channelId, oapp, ulnUserConfig)).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return false if configs with defaults are not identical', async () => {
            await fc.assert(
                fc.asyncProperty(
                    channelIdArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    async (channelId, oapp, ulnConfig) => {
                        // We only want to test againsts configs that are not
                        // equal to the default config
                        fc.pre(
                            ulnConfig.executor !== AddressZero ||
                                ulnConfig.optionalDVNThreshold !== 0 ||
                                ulnConfig.optionalDVNs.length !== 0
                        )

                        const ulnUserConfig: UlnReadUlnUserConfig = {
                            requiredDVNs: ulnConfig.requiredDVNs,
                        }

                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(ulnSdk.hasAppUlnConfig(channelId, oapp, ulnUserConfig)).resolves.toBeFalsy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return true if the configs are identical except for the dvn casing', async () => {
            await fc.assert(
                fc.asyncProperty(
                    channelIdArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    async (channelId, oapp, ulnConfig) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(channelId, oapp, {
                                ...ulnConfig,
                                requiredDVNs: ulnConfig.requiredDVNs.map(addChecksum),
                                optionalDVNs: ulnConfig.optionalDVNs.map(addChecksum),
                            })
                        ).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return true if the configs are identical except for the dvn sorting and casing', async () => {
            await fc.assert(
                fc.asyncProperty(
                    channelIdArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    async (channelId, oapp, ulnConfig) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(channelId, oapp, {
                                ...ulnConfig,
                                requiredDVNs: ulnConfig.requiredDVNs.map(addChecksum).sort(compareBytes32Ascending),
                                optionalDVNs: ulnConfig.optionalDVNs.map(addChecksum).sort(compareBytes32Ascending),
                            })
                        ).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return false if the confirmations are different', async () => {
            await fc.assert(
                fc.asyncProperty(
                    channelIdArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    evmAddressArbitrary,
                    async (channelId, oapp, ulnConfig, executor) => {
                        fc.pre(executor !== ulnConfig.executor)

                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(channelId, oapp, {
                                ...ulnConfig,
                                executor,
                            })
                        ).resolves.toBeFalsy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return false if the optionalDVNThresholds are different', async () => {
            await fc.assert(
                fc.asyncProperty(
                    channelIdArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    fc.integer(),
                    async (channelId, oapp, ulnConfig, optionalDVNThreshold) => {
                        fc.pre(optionalDVNThreshold !== ulnConfig.optionalDVNThreshold)

                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(channelId, oapp, {
                                ...ulnConfig,
                                optionalDVNThreshold,
                            })
                        ).resolves.toBeFalsy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return false if the requiredDVNs are different', async () => {
            await fc.assert(
                fc.asyncProperty(
                    channelIdArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    dvnsArbitrary,
                    async (channelId, oapp, ulnConfig, extraRequiredDVNs) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(channelId, oapp, {
                                ...ulnConfig,
                                requiredDVNs: [...ulnConfig.requiredDVNs, ...extraRequiredDVNs],
                            })
                        ).resolves.toBeFalsy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return false if the optionalDVNs are different', async () => {
            await fc.assert(
                fc.asyncProperty(
                    channelIdArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    dvnsArbitrary,
                    async (channelId, oapp, ulnConfig, extraOptionalDVNs) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(channelId, oapp, {
                                ...ulnConfig,
                                optionalDVNs: [...ulnConfig.optionalDVNs, ...extraOptionalDVNs],
                            })
                        ).resolves.toBeFalsy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should sort requiredDVNs and optionalDVNs before encoding', async () => {
            fc.assert(
                fc.property(dvnsArbitrary, (dvns) => {
                    const sortedDvns = [...dvns].sort((a, b) => a.localeCompare(b))
                    const ulnConfigUnsorted: Uln302UlnConfig = {
                        confirmations: BigInt(100),
                        optionalDVNThreshold: 0,
                        optionalDVNs: dvns,
                        requiredDVNs: dvns,
                    }

                    const ulnConfigSorted: Uln302UlnConfig = {
                        ...ulnConfigUnsorted,
                        optionalDVNs: sortedDvns,
                        requiredDVNs: sortedDvns,
                    }

                    const ulnConfigEncodedUnsorted = ulnSdk.encodeUlnConfig(ulnConfigUnsorted)
                    const ulnConfigEncodedSorted = ulnSdk.encodeUlnConfig(ulnConfigSorted)
                    expect(ulnConfigEncodedSorted).toBe(ulnConfigEncodedUnsorted)
                }),
                { numRuns: 20 }
            )
        })


it('should sort requiredDVNs and optionalDVNs', async () => {
            await fc.assert(
                fc.asyncProperty(endpointArbitrary, dvnsArbitrary, async (eid, dvns) => {
                    const sortedDvns = [...dvns].sort((a, b) => a.localeCompare(b))
                    const ulnConfigUnsorted: Uln302UlnConfig = {
                        confirmations: BigInt(100),
                        optionalDVNThreshold: 0,
                        optionalDVNs: dvns,
                        requiredDVNs: dvns,
                    }

                    const ulnConfigSorted: Uln302UlnConfig = {
                        ...ulnConfigUnsorted,
                        optionalDVNs: sortedDvns,
                        requiredDVNs: sortedDvns,
                    }

                    // Let's check that both the sorted and the unsorted config produce the same transaction
                    const transactionUnsorted = await ulnSdk.setDefaultUlnConfig(eid, ulnConfigUnsorted)
                    const transactionsSorted = await ulnSdk.setDefaultUlnConfig(eid, ulnConfigSorted)
                    expect(transactionUnsorted).toEqual(transactionsSorted)

                    // And let's check that the encoding call is correct and the DVNs are sorted
                    expect(transactionsSorted.data).toBe(
                        ulnSdk.contract.contract.interface.encodeFunctionData('setDefaultUlnConfigs', [
                            [
                                {
                                    eid,
                                    config: {
                                        confirmations: BigInt(100),
                                        optionalDVNThreshold: 0,
                                        optionalDVNs: sortedDvns.map(addChecksum),
                                        requiredDVNs: sortedDvns.map(addChecksum),
                                        requiredDVNCount: sortedDvns.length,
                                        optionalDVNCount: sortedDvns.length,
                                    },
                                },
                            ],
                        ])
                    )
                }),
                { numRuns: 20 }
            )
        })


it('should default the missing attributes', async () => {
            await fc.assert(
                fc.asyncProperty(endpointArbitrary, dvnsArbitrary, async (eid, dvns) => {
                    const sortedDvns = [...dvns].sort((a, b) => a.localeCompare(b))
                    const ulnUserConfig: Uln302UlnUserConfig = {
                        requiredDVNs: dvns,
                    }
                    const ulnConfig: Uln302UlnConfig = {
                        requiredDVNs: dvns,
                        confirmations: BigInt(0),
                        optionalDVNThreshold: 0,
                        optionalDVNs: [],
                    }

                    // Let's check that both the sorted and the unsorted config produce the same transaction
                    const transactionsWithDefaults = await ulnSdk.setDefaultUlnConfig(eid, ulnUserConfig)
                    const transactionsWithFullConfig = await ulnSdk.setDefaultUlnConfig(eid, ulnConfig)
                    expect(transactionsWithDefaults).toEqual(transactionsWithFullConfig)

                    // And let's check that the encoding call is correct and the DVNs are sorted
                    expect(transactionsWithDefaults.data).toBe(
                        ulnSdk.contract.contract.interface.encodeFunctionData('setDefaultUlnConfigs', [
                            [
                                {
                                    eid,
                                    config: {
                                        confirmations: ulnConfig.confirmations,
                                        optionalDVNThreshold: ulnConfig.optionalDVNThreshold,
                                        optionalDVNs: ulnConfig.optionalDVNs,
                                        requiredDVNs: sortedDvns.map(addChecksum),
                                        requiredDVNCount: ulnConfig.requiredDVNs.length,
                                        optionalDVNCount: ulnConfig.optionalDVNs.length,
                                    },
                                },
                            ],
                        ])
                    )
                }),
                { numRuns: 20 }
            )
        })


it('should return true if the configs are identical', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    async (eid, oapp, ulnConfig) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(eid, oapp, ulnConfig, Uln302ConfigType.Receive)
                        ).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return true if config has extra properties', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    fc.object(),
                    async (eid, oapp, ulnConfig, extra) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(
                                eid,
                                oapp,
                                {
                                    ...extra,
                                    ...ulnConfig,
                                },
                                Uln302ConfigType.Receive
                            )
                        ).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return true if configs with defaults are identical', async () => {
            await fc.assert(
                fc.asyncProperty(endpointArbitrary, evmAddressArbitrary, dvnsArbitrary, async (eid, oapp, dvns) => {
                    const ulnUserConfig: Uln302UlnUserConfig = {
                        requiredDVNs: dvns,
                    }
                    const ulnConfig: Uln302UlnConfig = {
                        requiredDVNs: dvns,
                        optionalDVNs: [],
                        optionalDVNThreshold: 0,
                        confirmations: BigInt(0),
                    }

                    getAppUlnConfigSpy.mockReset()
                    getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                    await expect(
                        ulnSdk.hasAppUlnConfig(eid, oapp, ulnUserConfig, Uln302ConfigType.Receive)
                    ).resolves.toBeTruthy()
                }),
                { numRuns: 20 }
            )
        })


it('should return false if configs with defaults are not identical', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    async (eid, oapp, ulnConfig) => {
                        // We only want to test againsts configs that are not
                        // equal to the default config
                        fc.pre(
                            ulnConfig.confirmations !== BigInt(0) ||
                                ulnConfig.optionalDVNThreshold !== 0 ||
                                ulnConfig.optionalDVNs.length !== 0
                        )

                        const ulnUserConfig: Uln302UlnUserConfig = {
                            requiredDVNs: ulnConfig.requiredDVNs,
                        }

                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(eid, oapp, ulnUserConfig, Uln302ConfigType.Receive)
                        ).resolves.toBeFalsy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return true if the configs are identical except for the dvn casing', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    async (eid, oapp, ulnConfig) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(
                                eid,
                                oapp,
                                {
                                    ...ulnConfig,
                                    requiredDVNs: ulnConfig.requiredDVNs.map(addChecksum),
                                    optionalDVNs: ulnConfig.optionalDVNs.map(addChecksum),
                                },
                                Uln302ConfigType.Receive
                            )
                        ).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return true if the configs are identical except for the dvn sorting and casing', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    async (eid, oapp, ulnConfig) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(
                                eid,
                                oapp,
                                {
                                    ...ulnConfig,
                                    requiredDVNs: ulnConfig.requiredDVNs.map(addChecksum).sort(compareBytes32Ascending),
                                    optionalDVNs: ulnConfig.optionalDVNs.map(addChecksum).sort(compareBytes32Ascending),
                                },
                                Uln302ConfigType.Receive
                            )
                        ).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return false if the confirmations are different', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    fc.bigInt(),
                    async (eid, oapp, ulnConfig, confirmations) => {
                        fc.pre(confirmations !== ulnConfig.confirmations)

                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(
                                eid,
                                oapp,
                                {
                                    ...ulnConfig,
                                    confirmations,
                                },
                                Uln302ConfigType.Receive
                            )
                        ).resolves.toBeFalsy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return false if the optionalDVNThresholds are different', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    fc.integer(),
                    async (eid, oapp, ulnConfig, optionalDVNThreshold) => {
                        fc.pre(optionalDVNThreshold !== ulnConfig.optionalDVNThreshold)

                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(
                                eid,
                                oapp,
                                {
                                    ...ulnConfig,
                                    optionalDVNThreshold,
                                },
                                Uln302ConfigType.Receive
                            )
                        ).resolves.toBeFalsy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return false if the requiredDVNs are different', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    dvnsArbitrary,
                    async (eid, oapp, ulnConfig, extraRequiredDVNs) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(
                                eid,
                                oapp,
                                {
                                    ...ulnConfig,
                                    requiredDVNs: [...ulnConfig.requiredDVNs, ...extraRequiredDVNs],
                                },
                                Uln302ConfigType.Receive
                            )
                        ).resolves.toBeFalsy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return false if the optionalDVNs are different', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    ulnConfigArbitrary,
                    dvnsArbitrary,
                    async (eid, oapp, ulnConfig, extraOptionalDVNs) => {
                        getAppUlnConfigSpy.mockReset()
                        getAppUlnConfigSpy.mockResolvedValue(ulnConfig)

                        await expect(
                            ulnSdk.hasAppUlnConfig(
                                eid,
                                oapp,
                                {
                                    ...ulnConfig,
                                    optionalDVNs: [...ulnConfig.optionalDVNs, ...extraOptionalDVNs],
                                },
                                Uln302ConfigType.Receive
                            )
                        ).resolves.toBeFalsy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return true if the configs are identical', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    executorConfigArbitrary,
                    async (eid, oapp, executorConfig) => {
                        getAppExecutorConfigSpy.mockReset()
                        getAppExecutorConfigSpy.mockResolvedValue(executorConfig)

                        await expect(ulnSdk.hasAppExecutorConfig(eid, oapp, executorConfig)).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return true if the configs are identical except for the executor casing', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    executorConfigArbitrary,
                    async (eid, oapp, executorConfig) => {
                        getAppExecutorConfigSpy.mockReset()
                        getAppExecutorConfigSpy.mockResolvedValue(executorConfig)

                        await expect(
                            ulnSdk.hasAppExecutorConfig(eid, oapp, {
                                ...executorConfig,
                                executor: addChecksum(executorConfig.executor),
                            })
                        ).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should return true if config has extra properties', async () => {
            await fc.assert(
                fc.asyncProperty(
                    endpointArbitrary,
                    evmAddressArbitrary,
                    executorConfigArbitrary,
                    fc.object(),
                    async (eid, oapp, executorConfig, extra) => {
                        getAppExecutorConfigSpy.mockReset()
                        getAppExecutorConfigSpy.mockResolvedValue(executorConfig)

                        await expect(
                            ulnSdk.hasAppExecutorConfig(eid, oapp, {
                                ...extra,
                                ...executorConfig,
                            })
                        ).resolves.toBeTruthy()
                    }
                ),
                { numRuns: 20 }
            )
        })


it('should reject if the address is a zeroish address', async () => {
            await fc.assert(
                fc.asyncProperty(pointArbitrary, zeroishAddressArbitrary, async (point, address) => {
                    const provider = new JsonRpcProvider()
                    const sdk = new EndpointV2(provider, point)

                    await expect(sdk.getUln302SDK(address)).rejects.toThrow(
                        /Uln302 cannot be instantiated: Uln302 address cannot be a zero value for Endpoint/
                    )
                })
            )
        })


it('should return a ULN302 if the address is a non-zeroish address', async () => {
            await fc.assert(
                fc.asyncProperty(pointArbitrary, evmAddressArbitrary, async (point, address) => {
                    fc.pre(!isZero(address))

                    const provider = new JsonRpcProvider()

                    const sdk = new EndpointV2(provider, point)
                    const uln302 = await sdk.getUln302SDK(address)

                    expect(uln302).toBeInstanceOf(Uln302)
                    expect(uln302.point).toEqual({ eid: point.eid, address })
                })
            )
        })


it('should return a tuple if the call succeeds', async () => {
            await fc.assert(
                fc.asyncProperty(
                    pointArbitrary,
                    endpointArbitrary,
                    evmAddressArbitrary,
                    evmAddressArbitrary,
                    fc.boolean(),
                    async (point, eid, oappAddress, libraryAddress, isDefault) => {
                        const provider = new JsonRpcProvider()
                        const sdk = new EndpointV2(provider, point)

                        jest.spyOn(provider, 'call').mockResolvedValue(
                            sdk.contract.contract.interface.encodeFunctionResult('getReceiveLibrary', [
                                libraryAddress,
                                isDefault,
                            ])
                        )

                        await expect(sdk.getReceiveLibrary(oappAddress, eid)).resolves.toEqual([
                            addChecksum(libraryAddress),
                            isDefault,
                        ])
                    }
                )
            )
        })


it('should return undefined as the default lib if the call fails with LZ_DefaultReceiveLibUnavailable', async () => {
            await fc.assert(
                fc.asyncProperty(
                    pointArbitrary,
                    endpointArbitrary,
                    evmAddressArbitrary,
                    async (point, eid, oappAddress) => {
                        const provider = new JsonRpcProvider()
                        const sdk = new EndpointV2(provider, point)
                        // The LZ_DefaultReceiveLibUnavailable error
                        const error = { data: '0x78e84d06' }

                        jest.spyOn(provider, 'call').mockRejectedValue(error)

                        await expect(sdk.getReceiveLibrary(oappAddress, eid)).resolves.toEqual([undefined, true])
                    }
                )
            )
        })


it('should reject if call fails but not with LZ_DefaultReceiveLibUnavailable', async () => {
            await fc.assert(
                fc.asyncProperty(
                    pointArbitrary,
                    endpointArbitrary,
                    evmAddressArbitrary,
                    async (point, eid, oappAddress) => {
                        const provider = new JsonRpcProvider()
                        const sdk = new EndpointV2(provider, point)
                        const error = { data: '0x86957466' }

                        jest.spyOn(provider, 'call').mockRejectedValue(error)

                        await expect(sdk.getReceiveLibrary(oappAddress, eid)).rejects.toEqual(error)
                    }
                )
            )
        })


it('should return an address if the call succeeds', async () => {
            await fc.assert(
                fc.asyncProperty(
                    pointArbitrary,
                    endpointArbitrary,
                    evmAddressArbitrary,
                    evmAddressArbitrary,
                    async (point, eid, oappAddress, libraryAddress) => {
                        const provider = new JsonRpcProvider()
                        const sdk = new EndpointV2(provider, point)

                        jest.spyOn(provider, 'call').mockResolvedValue(
                            sdk.contract.contract.interface.encodeFunctionResult('getSendLibrary', [libraryAddress])
                        )

                        await expect(sdk.getSendLibrary(oappAddress, eid)).resolves.toEqual(addChecksum(libraryAddress))
                    }
                )
            )
        })


it('should return undefined if the call fails with LZ_DefaultSendLibUnavailable', async () => {
            await fc.assert(
                fc.asyncProperty(
                    pointArbitrary,
                    endpointArbitrary,
                    evmAddressArbitrary,
                    async (point, eid, oappAddress) => {
                        const provider = new JsonRpcProvider()
                        const sdk = new EndpointV2(provider, point)
                        // The LZ_DefaultReceiveLibUnavailable error
                        const error = { data: '0x6c1ccdb5' }

                        jest.spyOn(provider, 'call').mockRejectedValue(error)

                        await expect(sdk.getSendLibrary(oappAddress, eid)).resolves.toEqual(undefined)
                    }
                )
            )
        })


it('should reject if call fails but not with LZ_DefaultSendLibUnavailable', async () => {
            await fc.assert(
                fc.asyncProperty(
                    pointArbitrary,
                    endpointArbitrary,
                    evmAddressArbitrary,
                    async (point, eid, oappAddress) => {
                        const provider = new JsonRpcProvider()
                        const sdk = new EndpointV2(provider, point)
                        const error = { data: '0x86957466' }

                        jest.spyOn(provider, 'call').mockRejectedValue(error)

                        await expect(sdk.getSendLibrary(oappAddress, eid)).rejects.toEqual(error)
                    }
                )
            )
        })


it('should call onStart & onSuccess when the callback resolves', async () => {
                await fc.assert(
                    fc.asyncProperty(fc.array(fc.anything()), fc.anything(), async (args, returnValue) => {
                        const fn = jest.fn().mockResolvedValue(returnValue)
                        const onStart = jest.fn().mockImplementation((logger: Logger) => logger.debug(`onStart`))
                        const onSuccess = jest.fn().mockImplementation((logger: Logger) => logger.debug(`onSuccess`))

                        await expect(withAsyncLogger(fn, { onStart, onSuccess })(...args)).resolves.toBe(returnValue)

                        expect(onStart).toHaveBeenCalledWith(expect.anything(), args)
                        expect(onSuccess).toHaveBeenCalledWith(expect.anything(), args, returnValue)
                        expect(onStart).toHaveBeenCalledBefore(onSuccess)
                    })
                )
            })


it('should call onStart & onFailure when callback rejects', async () => {
                await fc.assert(
                    fc.asyncProperty(fc.array(fc.anything()), fc.anything(), async (args, error) => {
                        const fn = jest.fn().mockRejectedValue(error)
                        const onStart = jest.fn().mockImplementation((logger: Logger) => logger.debug(`onStart`))
                        const onError = jest.fn().mockImplementation((logger: Logger) => logger.debug(`onSuccess`))

                        await expect(withAsyncLogger(fn, { onStart, onError })(...args)).rejects.toBe(error)

                        expect(onStart).toHaveBeenCalledWith(expect.anything(), args)
                        expect(onError).toHaveBeenCalledWith(expect.anything(), args, error)
                        expect(onStart).toHaveBeenCalledBefore(onError)
                    })
                )
            })


it('should resolve if onSuccess call throws', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        fc.array(fc.anything()),
                        fc.anything(),
                        fc.anything(),
                        async (args, returnValue, loggerError) => {
                            const fn = jest.fn().mockResolvedValue(returnValue)
                            const onStart = jest.fn().mockImplementation((logger: Logger) => logger.debug(`onStart`))
                            const onSuccess = jest.fn().mockImplementation(() => {
                                throw loggerError
                            })

                            await expect(withAsyncLogger(fn, { onStart, onSuccess })(...args)).resolves.toBe(
                                returnValue
                            )

                            expect(onStart).toHaveBeenCalledWith(expect.anything(), args)
                            expect(onSuccess).toHaveBeenCalledWith(expect.anything(), args, returnValue)
                            expect(onStart).toHaveBeenCalledBefore(onSuccess)
                        }
                    )
                )
            })


it('should reject with the original error if onError callback throws', async () => {
                await fc.assert(
                    fc.asyncProperty(
                        fc.array(fc.anything()),
                        fc.anything(),
                        fc.anything(),
                        async (args, error, loggerError) => {
                            const fn = jest.fn().mockRejectedValue(error)
                            const onStart = jest.fn().mockImplementation((logger: Logger) => logger.debug(`onStart`))
                            const onError = jest.fn().mockImplementation(() => {
                                throw loggerError
                            })

                            await expect(withAsyncLogger(fn, { onStart, onError })(...args)).rejects.toBe(error)

                            expect(onStart).toHaveBeenCalledWith(expect.anything(), args)
                            expect(onError).toHaveBeenCalledWith(expect.anything(), args, error)
                            expect(onStart).toHaveBeenCalledBefore(onError)
                        }
                    )
                )
            })


it('should return an empty array when called with an array of nulls and undefineds', () => {
            fc.assert(
                fc.property(fc.array(nullableArbitrary), (transactions) => {
                    expect(flattenTransactions(transactions)).toEqual([])
                })
            )
        })


it('should remove any nulls or undefineds', () => {
            fc.assert(
                fc.property(fc.array(fc.oneof(transactionArbitrary, nullableArbitrary)), (transactions) => {
                    const flattened = flattenTransactions(transactions)

                    for (const transaction of flattened) {
                        expect(transaction).not.toBeNull()
                        expect(transaction).not.toBeUndefined()
                    }
                })
            )
        })


it('should flatten any arrays', () => {
            fc.assert(
                fc.property(
                    fc.array(fc.oneof(transactionArbitrary, nullableArbitrary, fc.array(transactionArbitrary))),
                    (transactions) => {
                        const flattened = flattenTransactions(transactions)

                        for (const transaction of flattened) {
                            expect(transaction).not.toBeInstanceOf(Array)
                        }
                    }
                )
            )
        })


it('should return a map with containing all the transactions passed in', () => {
            fc.assert(
                fc.property(fc.array(transactionArbitrary), (transactions) => {
                    const grouped = groupTransactionsByEid(transactions)

                    for (const transaction of transactions) {
                        expect(grouped.get(transaction.point.eid)).toContain(transaction)
                    }
                })
            )
        })


it('should preserve the order of transaction per group', () => {
            fc.assert(
                fc.property(fc.array(transactionArbitrary), (transactions) => {
                    const grouped = groupTransactionsByEid(transactions)

                    for (const transactionsForEid of grouped.values()) {
                        // Here we want to make sure that within a group of transactions,
                        // no transactions have changed order
                        //
                        // The logic here goes something like this:
                        // - We look for the indices of transactions from the grouped array in the original array
                        // - If two transactions swapped places, this array would then contain an inversion
                        //   (transaction at an earlier index in the grouped array would appear after a transaction
                        //   at a later index). So what we do is remove the inversions by sorting the array of indices
                        //   and make sure this sorted array matches the original one
                        const transactionIndices = transactionsForEid.map((t) => transactions.indexOf(t))
                        const sortedTransactionIndices = transactionIndices.slice().sort()

                        expect(transactionIndices).toEqual(sortedTransactionIndices)
                    }
                })
            )
        })


it('should parse successfully', () => {
                fc.assert(
                    fc.property(pointArbitrary, good, (point, config) => {
                        expect(schema.safeParse({ point, config }).success).toBeTruthy()
                    })
                )
            })


it('should not parse', () => {
                fc.assert(
                    fc.property(pointArbitrary, bad, (point, config) => {
                        expect(schema.safeParse({ point, config }).success).toBeFalsy()
                    })
                )
            })


it('should parse successfully', () => {
                fc.assert(
                    fc.property(vectorArbitrary, good, (vector, config) => {
                        expect(schema.safeParse({ vector, config }).success).toBeTruthy()
                    })
                )
            })


it('should not parse', () => {
                fc.assert(
                    fc.property(vectorArbitrary, bad, (vector, config) => {
                        expect(schema.safeParse({ vector, config }).success).toBeFalsy()
                    })
                )
            })


it('should work for non-negative bigints', () => {
            fc.assert(
                fc.property(fc.bigInt({ min: BigInt(0) }), (value) => {
                    expect(UIntBigIntSchema.parse(value)).toBe(value)
                })
            )
        })


it('should not work for negative bigints', () => {
            fc.assert(
                fc.property(fc.bigInt({ max: BigInt(-1) }), (value) => {
                    expect(() => UIntBigIntSchema.parse(value)).toThrow()
                })
            )
        })


it('should not work for negative integer strings', () => {
            fc.assert(
                fc.property(fc.integer({ max: -1 }), (value) => {
                    expect(() => UIntNumberSchema.parse(String(value))).toThrow()
                })
            )
        })

Summary: `UIntNumberSchema.parse` throws an error when attempting to parse negative integer strings.


it('should be true for value equal vector', () => {
                fc.assert(
                    fc.property(vectorArbitrary, (vector) => {
                        expect(areVectorsEqual(vector, { ...vector })).toBeTruthy()
                    })
                )
            })

Summary: `areVectorsEqual` returns true when comparing a vector object to itself.


it('should return true if two points are on the same stage', () => {
                fc.assert(
                    fc.property(endpointArbitrary, endpointArbitrary, addressArbitrary, (eid1, eid2, address) => {
                        fc.pre(endpointIdToStage(eid1) === endpointIdToStage(eid2))

                        expect(
                            isVectorPossible({ from: { eid: eid1, address }, to: { eid: eid2, address } })
                        ).toBeTruthy()
                    })
                )
            })

Summary: `isVectorPossible` returns true for two points when their endpoint IDs correspond to the same stage.


it('should not add a duplicate node', () => {
                fc.assert(
                    fc.property(nodeArbitrary, (node) => {
                        const builder = new OmniGraphBuilder()

                        builder.addNodes(node, node)
                        expect(builder.nodes).toEqual([node])
                    })
                )
            })

Summary: Adding the same node twice to `OmniGraphBuilder` should result in a single node in the graph.


it('should remove a node at a specified point', () => {
                fc.assert(
                    fc.property(nodeArbitrary, (node) => {
                        const builder = new OmniGraphBuilder()

                        builder.addNodes(node)
                        builder.removeNodeAt(node.point)
                        expect(builder.nodes).toEqual([])
                    })
                )
            })

Summary: Removing a node at a specified point in `OmniGraphBuilder` results in an empty node list.


it('should not remove nodes at different points', () => {
                fc.assert(
                    fc.property(nodeArbitrary, nodeArbitrary, (nodeA, nodeB) => {
                        fc.pre(!arePointsEqual(nodeA.point, nodeB.point))

                        const builder = new OmniGraphBuilder()

                        builder.addNodes(nodeA, nodeB)
                        builder.removeNodeAt(nodeA.point)
                        expect(builder.nodes).toEqual([nodeB])
                    })
                )
            })

Summary: `OmniGraphBuilder` should retain nodes with differing points when one is removed.


it('should not do anything when there are no edges', () => {
                fc.assert(
                    fc.property(edgeArbitrary, (edge) => {
                        fc.pre(isVectorPossible(edge.vector))

                        const builder = new OmniGraphBuilder()

                        builder.removeEdgeAt(edge.vector)
                        expect(builder.edges).toEqual([])
                    })
                )
            })

Summary: `OmniGraphBuilder` retains an empty edge list when attempting to remove edges from a vector that doesn't exist.


it('should return node when there is a node at a specified point', () => {
                fc.assert(
                    fc.property(nodesArbitrary, (nodes) => {
                        const node = nodes.at(-1)
                        fc.pre(node != null)

                        const builder = new OmniGraphBuilder()

                        builder.addNodes(...nodes)
                        expect(builder.getNodeAt(node!.point)).toBe(node)
                    })
                )
            })

Summary: `OmniGraphBuilder` returns the correct node when a node exists at a specified point.


it('should return undefined when there are no edges', () => {
                const builder = new OmniGraphBuilder()

                fc.assert(
                    fc.property(vectorArbitrary, (vector) => {
                        expect(builder.getEdgeAt(vector)).toBeUndefined()
                    })
                )
            })

Summary: `OmniGraphBuilder.getEdgeAt` returns undefined when there are no edges.


it('should return the first transaction as failed if createSigner fails', async () => {
                    await fc.assert(
                        fc.asyncProperty(fc.array(transactionArbitrary), async (transactions) => {
                            const signerFactory: OmniSignerFactory = jest
                                .fn()
                                .mockImplementation((eid: EndpointId) => Promise.reject(new Error(`So sorry ${eid}`)))
                            const signAndSendTransactions = createSignAndSend(signerFactory)

                            // Now we send all the transactions to the flow and observe the output
                            const [successful, errors, pending] = await signAndSendTransactions(transactions)

                            const grouped = groupTransactionsByEid(transactions)

                            // We expect none of the transactions to go through
                            expect(successful).toEqual([])
                            // We expect the errors to contain the first transaction and the wrapped error from the signer factory
                            expect(errors).toEqual(
                                Array.from(grouped.entries()).map(([eid, transactions]) => ({
                                    error: new Error(
                                        `Failed to create a signer for ${formatEid(eid)}: ${new Error(`So sorry ${eid}`)}`
                                    ),
                                    transaction: transactions[0],
                                }))
                            )
                            // And we expect all the transactions to be pending
                            expect(pending).toContainAllValues(
                                Array.from(grouped.entries()).flatMap(([, transactions]) => transactions)
                            )
                        })
                    )
                })

Summary: When `createSigner` fails, the first transaction should be marked as failed with the appropriate error, while no transactions are successful, and all are pending.


it('should return identity for bytes32', () => {
            fc.assert(
                fc.property(evmBytes32Arbitrary, (bytes) => {
                    expect(makeBytes32(bytes)).toBe(bytes)
                })
            )
        })

Summary: `makeBytes32` returns the same value when given `bytes32`.


it('should return true for identical UInt8Arrays', () => {
            fc.assert(
                fc.property(fc.uint8Array({ minLength: 1 }), (bytes) => {
                    expect(areBytes32Equal(bytes, bytes)).toBe(true)
                })
            )
        })

Summary: `areBytes32Equal` returns true for identical `UInt8Arrays`.


it('should return true for a UInt8Array & its hex representation', () => {
            fc.assert(
                fc.property(fc.uint8Array({ minLength: 1, maxLength: 32 }), (bytes) => {
                    expect(areBytes32Equal(bytes, makeBytes32(bytes))).toBe(true)
                })
            )
        })

Summary: `areBytes32Equal` returns true when comparing a `UInt8Array` with its hex representation created by `makeBytes32`.


it('should return false with non-zero address', () => {
            fc.assert(
                fc.property(evmAddressArbitrary, (address) => {
                    fc.pre(address !== AddressZero)

                    expect(isZero(address)).toBe(false)
                })
            )
        })

Summary: `isZero` should return false when given a non-zero address.


it('should return false with non-zero bytes32', () => {
            fc.assert(
                fc.property(evmBytes32Arbitrary, (address) => {
                    fc.pre(address !== ZERO_BYTES)

                    expect(isZero(address)).toBe(false)
                })
            )
        })

Summary: `isZero` returns false for non-zero `bytes32` values.


it('should return false with a non-zero UInt8Array', () => {
            fc.assert(
                fc.property(fc.uint8Array({ minLength: 1 }), (bytes) => {
                    fc.pre(bytes.some((byte) => byte !== 0))

                    expect(isZero(bytes)).toBe(false)
                })
            )
        })

Summary: `isZero` should return false for a `UInt8Array` containing non-zero elements.


it('should return address with non-zero address', () => {
            fc.assert(
                fc.property(evmAddressArbitrary, (address) => {
                    fc.pre(address !== AddressZero)

                    expect(ignoreZero(address)).toBe(address)
                })
            )
        })

Summary: `ignoreZero` returns the same address if it is not the zero address.


it('should execute one by one', async () => {
            await fc.assert(
                fc.asyncProperty(valuesArbitrary, async (values) => {
                    fc.pre(values.length > 0)

                    const tasks = values.map((value) => jest.fn().mockResolvedValue(value))

                    await sequence(tasks)

                    tasks.reduce((task1, task2) => {
                        return expect(task1).toHaveBeenCalledBefore(task2), task2
                    })
                })
            )
        })

Summary: Ensures that a sequence of tasks is executed in order, with each task being called before the next.


it('should resolve if the first task resolves', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, valuesArbitrary, async (value, errors) => {
                    const task = jest.fn().mockResolvedValue(value)
                    const tasks = errors.map((error) => jest.fn().mockRejectedValue(error))

                    expect(await first([task, ...tasks])).toBe(value)

                    // Make sure none of the other factories got called
                    for (const factory of tasks) {
                        expect(factory).not.toHaveBeenCalled()
                    }
                })
            )
        })


it('should resolve with the first successful task', async () => {
            await fc.assert(
                fc.asyncProperty(valuesArbitrary, valueArbitrary, async (errors, value) => {
                    const tasks = errors.map((error) => jest.fn().mockRejectedValue(error))
                    const task = jest.fn().mockResolvedValue(value)

                    expect(await first([...tasks, task])).toBe(value)

                    // Make sure all the tasks got called
                    for (const factory of tasks) {
                        expect(factory).toHaveBeenCalledTimes(1)
                    }

                    expect(task).toHaveBeenCalledTimes(1)
                })
            )
        })


it('should reject with the last rejected task error', async () => {
            await fc.assert(
                fc.asyncProperty(valuesArbitrary, valueArbitrary, async (errors, error) => {
                    const tasks = errors.map((error) => jest.fn().mockRejectedValue(error))
                    const task = jest.fn().mockRejectedValue(error)

                    await expect(first([...tasks, task])).rejects.toBe(error)

                    // Make sure all the tasks got called
                    for (const factory of tasks) {
                        expect(factory).toHaveBeenCalledTimes(1)
                    }

                    expect(task).toHaveBeenCalledTimes(1)
                })
            )
        })


it('should resolve if the first factory resolves', async () => {
            await fc.assert(
                fc.asyncProperty(valueArbitrary, valuesArbitrary, async (value, values) => {
                    const successful = jest.fn().mockResolvedValue(value)
                    const successfulOther = values.map((value) => jest.fn().mockResolvedValue(value))
                    const factory = firstFactory(successful, ...successfulOther)

                    expect(await factory()).toBe(value)

                    // Make sure none of the other factories got called
                    for (const factory of successfulOther) {
                        expect(factory).not.toHaveBeenCalled()
                    }
                })
            )
        })


it('should resolve with the first successful factory', async () => {
            await fc.assert(
                fc.asyncProperty(valuesArbitrary, valueArbitrary, async (errors, value) => {
                    const failing = errors.map((error) => jest.fn().mockRejectedValue(error))
                    const successful = jest.fn().mockResolvedValue(value)
                    const factory = firstFactory(...failing, successful)

                    expect(await factory()).toBe(value)

                    // Make sure all the tasks got called
                    for (const factory of failing) {
                        expect(factory).toHaveBeenCalledTimes(1)
                    }
                })
            )
        })