"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.spokePoolFixture = exports.zeroAddress = void 0;
exports.getRelayHash = getRelayHash;
exports.getV3RelayHash = getV3RelayHash;
exports.getLegacyV3RelayHash = getLegacyV3RelayHash;
exports.getDepositParams = getDepositParams;
exports.getFillRelayParams = getFillRelayParams;
exports.getFillRelayUpdatedFeeParams = getFillRelayUpdatedFeeParams;
exports.getExecuteSlowRelayParams = getExecuteSlowRelayParams;
exports.modifyRelayHelper = modifyRelayHelper;
exports.getUpdatedV3DepositSignature = getUpdatedV3DepositSignature;
exports.deployMockSpokePoolCaller = deployMockSpokePoolCaller;
exports.deploySpokePool = deploySpokePool;
const tslib_1 = require("tslib");
require("@nomiclabs/hardhat-ethers");
require("@openzeppelin/hardhat-upgrades");
const hardhat_1 = tslib_1.__importDefault(require("hardhat"));
const ethers_1 = require("ethers");
const getContractFactory_1 = require("../utils/getContractFactory");
const constants_1 = require("../constants");
Object.defineProperty(exports, "zeroAddress", { enumerable: true, get: function () { return constants_1.zeroAddress; } });
const utils_1 = require("./utils");
const { defaultAbiCoder, keccak256 } = ethers_1.ethers.utils;
function getRelayHash(_depositor, _recipient, _depositId, _originChainId, _destinationChainId, _destinationToken, _amount, _realizedLpFeePct, _relayerFeePct, _message) {
    const relayData = {
        depositor: _depositor,
        recipient: _recipient,
        destinationToken: _destinationToken,
        amount: _amount || constants_1.amountToDeposit,
        originChainId: _originChainId.toString(),
        destinationChainId: _destinationChainId.toString(),
        realizedLpFeePct: _realizedLpFeePct || constants_1.realizedLpFeePct,
        relayerFeePct: _relayerFeePct || constants_1.depositRelayerFeePct,
        depositId: _depositId.toString(),
        message: _message || "0x",
    };
    const relayHash = keccak256(defaultAbiCoder.encode([
        "tuple(address depositor, address recipient, address destinationToken, uint256 amount, uint256 originChainId, uint256 destinationChainId, int64 realizedLpFeePct, int64 relayerFeePct, uint32 depositId, bytes message)",
    ], [relayData]));
    return { relayHash, relayData };
}
function getV3RelayHash(relayData, destChainId) {
    return keccak256(defaultAbiCoder.encode([
        "tuple(bytes32 depositor, bytes32 recipient, bytes32 exclusiveRelayer, bytes32 inputToken, bytes32 outputToken, uint256 inputAmount, uint256 outputAmount, uint256 originChainId, uint256 depositId, uint32 fillDeadline, uint32 exclusivityDeadline, bytes message)",
        "uint256 destinationChainId",
    ], [relayData, destChainId]));
}
function getLegacyV3RelayHash(relayData, destChainId) {
    return keccak256(defaultAbiCoder.encode([
        "tuple(address depositor, address recipient, address exclusiveRelayer, address inputToken, address outputToken, uint256 inputAmount, uint256 outputAmount, uint256 originChainId, uint32 depositId, uint32 fillDeadline, uint32 exclusivityDeadline, bytes message)",
        "uint256 destinationChainId",
    ], [relayData, destChainId]));
}
function getDepositParams(args) {
    return [
        args.recipient ?? (0, constants_1.randomAddress)(),
        args.originToken,
        args.amount.toString(),
        args.destinationChainId.toString(),
        args.relayerFeePct.toString(),
        args.quoteTimestamp.toString(),
        args.message ?? "0x",
        args?.maxCount?.toString() ?? constants_1.maxUint256.toString(),
    ];
}
function getFillRelayParams(_relayData, _maxTokensToSend, _repaymentChain, _maxCount) {
    return [
        _relayData.depositor,
        _relayData.recipient,
        _relayData.destinationToken,
        _relayData.amount.toString(),
        _maxTokensToSend.toString(),
        _repaymentChain ? _repaymentChain.toString() : constants_1.repaymentChainId.toString(),
        _relayData.originChainId,
        _relayData.realizedLpFeePct.toString(),
        _relayData.relayerFeePct.toString(),
        _relayData.depositId,
        _relayData.message || "0x",
        _maxCount ? _maxCount.toString() : constants_1.maxUint256.toString(),
    ];
}
function getFillRelayUpdatedFeeParams(_relayData, _maxTokensToSend, _updatedFee, _signature, _repaymentChain, _updatedRecipient, _updatedMessage, _maxCount) {
    return [
        _relayData.depositor,
        _relayData.recipient,
        _updatedRecipient || _relayData.recipient,
        _relayData.destinationToken,
        _relayData.amount.toString(),
        _maxTokensToSend.toString(),
        _repaymentChain ? _repaymentChain.toString() : constants_1.repaymentChainId.toString(),
        _relayData.originChainId,
        _relayData.realizedLpFeePct.toString(),
        _relayData.relayerFeePct.toString(),
        _updatedFee.toString(),
        _relayData.depositId,
        _relayData.message,
        _updatedMessage || _relayData.message,
        _signature,
        _maxCount ? _maxCount.toString() : constants_1.maxUint256.toString(),
    ];
}
function getExecuteSlowRelayParams(_depositor, _recipient, _destToken, _amount, _originChainId, _realizedLpFeePct, _relayerFeePct, _depositId, _relayerRefundId, _message, _payoutAdjustment, _proof) {
    return [
        _depositor,
        _recipient,
        _destToken,
        _amount.toString(),
        _originChainId.toString(),
        _realizedLpFeePct.toString(),
        _relayerFeePct.toString(),
        _depositId.toString(),
        _relayerRefundId.toString(),
        _message,
        _payoutAdjustment.toString(),
        _proof,
    ];
}
async function modifyRelayHelper(modifiedRelayerFeePct, depositId, originChainId, depositor, updatedRecipient, updatedMessage) {
    const typedData = {
        types: {
            UpdateDepositDetails: [
                { name: "depositId", type: "uint32" },
                { name: "originChainId", type: "uint256" },
                { name: "updatedRelayerFeePct", type: "int64" },
                { name: "updatedRecipient", type: "address" },
                { name: "updatedMessage", type: "bytes" },
            ],
        },
        domain: {
            name: "ACROSS-V2",
            version: "1.0.0",
            chainId: Number(originChainId),
        },
        message: {
            depositId,
            originChainId,
            updatedRelayerFeePct: modifiedRelayerFeePct,
            updatedRecipient,
            updatedMessage,
        },
    };
    const signature = await depositor._signTypedData(typedData.domain, typedData.types, typedData.message);
    return { signature };
}
async function getUpdatedV3DepositSignature(depositor, depositId, originChainId, updatedOutputAmount, updatedRecipient, updatedMessage) {
    const typedData = {
        types: {
            UpdateDepositDetails: [
                { name: "depositId", type: "uint256" },
                { name: "originChainId", type: "uint256" },
                { name: "updatedOutputAmount", type: "uint256" },
                { name: "updatedRecipient", type: "bytes32" },
                { name: "updatedMessage", type: "bytes" },
            ],
        },
        domain: {
            name: "ACROSS-V2",
            version: "1.0.0",
            chainId: originChainId,
        },
        message: {
            depositId,
            originChainId,
            updatedOutputAmount,
            updatedRecipient,
            updatedMessage,
        },
    };
    return await depositor._signTypedData(typedData.domain, typedData.types, typedData.message);
}
async function deployMockSpokePoolCaller(spokePool, rootBundleId, leaf, proof) {
    return await (await (0, getContractFactory_1.getContractFactory)("MockCaller", (await hardhat_1.default.ethers.getSigners())[0])).deploy(spokePool.address, rootBundleId, leaf, proof);
}
async function deploySpokePool(ethers, spokePoolName = "MockSpokePool") {
    const [deployerWallet, crossChainAdmin, hubPool] = await ethers.getSigners();
    const weth = await (await (0, getContractFactory_1.getContractFactory)("WETH9", deployerWallet)).deploy();
    const erc20 = await (await (0, getContractFactory_1.getContractFactory)("ExpandedERC20", deployerWallet)).deploy("USD Coin", "USDC", 18);
    await erc20.addMember(constants_1.TokenRolesEnum.MINTER, deployerWallet.address);
    const unwhitelistedErc20 = await (await (0, getContractFactory_1.getContractFactory)("ExpandedERC20", deployerWallet)).deploy("Unwhitelisted", "UNWHITELISTED", 18);
    await unwhitelistedErc20.addMember(constants_1.TokenRolesEnum.MINTER, deployerWallet.address);
    const destErc20 = await (await (0, getContractFactory_1.getContractFactory)("ExpandedERC20WithBlacklist", deployerWallet)).deploy("L2 USD Coin", "L2 USDC", 18);
    await destErc20.addMember(constants_1.TokenRolesEnum.MINTER, deployerWallet.address);
    const spokePool = await hardhat_1.default.upgrades.deployProxy(await (0, getContractFactory_1.getContractFactory)(spokePoolName, deployerWallet), [0, crossChainAdmin.address, hubPool.address], { kind: "uups", unsafeAllow: ["delegatecall"], constructorArgs: [weth.address] });
    await spokePool.setChainId(constants_1.destinationChainId);
    const erc1271 = await (await (0, getContractFactory_1.getContractFactory)("MockERC1271", deployerWallet)).deploy(deployerWallet.address);
    return {
        weth,
        erc20,
        spokePool,
        unwhitelistedErc20,
        destErc20,
        erc1271,
    };
}
exports.spokePoolFixture = (0, utils_1.createFixture)(async () => {
    return await deploySpokePool(hardhat_1.default.ethers);
});
//# sourceMappingURL=SpokePool.Fixture.js.map