"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable no-unused-expressions */
const constants_1 = require("@across-protocol/constants");
const consts = __importStar(require("../constants"));
const utils_1 = require("../../../../utils/utils");
const HubPool_Fixture_1 = require("../fixtures/HubPool.Fixture");
const MerkleLib_utils_1 = require("../MerkleLib.utils");
const common_1 = require("@uma/common");
let hubPool, adapter, weth, usdc, mockSpoke, timer;
let l2Weth, l2Usdc;
let owner, dataWorker;
let liquidityProvider;
let l1CrossDomainMessenger, l1StandardBridge, opUSDCBridge;
const { WORLD_CHAIN } = constants_1.CHAIN_IDs;
const opUSDCBridgeABI = [
    {
        inputs: [
            { internalType: "address", name: "_to", type: "address" },
            { internalType: "uint256", name: "_amount", type: "uint256" },
            { internalType: "uint32", name: "_minGasLimit", type: "uint32" },
        ],
        name: "sendMessage",
        outputs: [],
        stateMutability: "nonpayable",
        type: "function",
    },
];
describe("OP Adapter", function () {
    beforeEach(async function () {
        [owner, dataWorker, liquidityProvider] = await utils_1.ethers.getSigners();
        ({ weth, l2Weth, usdc, l2Usdc, hubPool, mockSpoke, timer } = await (0, HubPool_Fixture_1.hubPoolFixture)());
        await (0, utils_1.seedWallet)(dataWorker, [usdc], weth, consts.amountToLp);
        await (0, utils_1.seedWallet)(liquidityProvider, [usdc], weth, consts.amountToLp.mul(10));
        await (0, HubPool_Fixture_1.enableTokensForLP)(owner, hubPool, weth, [weth, usdc]);
        await weth.connect(liquidityProvider).approve(hubPool.address, consts.amountToLp);
        await hubPool.connect(liquidityProvider).addLiquidity(weth.address, consts.amountToLp);
        await weth.connect(dataWorker).approve(hubPool.address, consts.bondAmount.mul(10));
        await usdc.connect(liquidityProvider).approve(hubPool.address, consts.amountToLp);
        await hubPool.connect(liquidityProvider).addLiquidity(usdc.address, consts.amountToLp);
        await usdc.connect(dataWorker).approve(hubPool.address, consts.bondAmount.mul(10));
        l1CrossDomainMessenger = await (0, utils_1.createFake)("L1CrossDomainMessenger");
        l1StandardBridge = await (0, utils_1.createFake)("L1StandardBridge");
        opUSDCBridge = await (0, utils_1.createFakeFromABI)(opUSDCBridgeABI);
        adapter = await (await (0, utils_1.getContractFactory)("OP_Adapter", owner)).deploy(weth.address, usdc.address, l1CrossDomainMessenger.address, l1StandardBridge.address, opUSDCBridge.address, common_1.ZERO_ADDRESS, (0, utils_1.toBN)("322"));
        // Seed the HubPool some funds so it can send L1->L2 messages.
        await hubPool.connect(liquidityProvider).loadEthForL2Calls({ value: (0, utils_1.toWei)("1") });
        await hubPool.setCrossChainContracts(WORLD_CHAIN, adapter.address, mockSpoke.address);
        await hubPool.setPoolRebalanceRoute(WORLD_CHAIN, usdc.address, l2Usdc);
        await hubPool.setPoolRebalanceRoute(WORLD_CHAIN, weth.address, l2Weth);
    });
    it("Correctly routes USDC via the configured OP USDC bridge", async function () {
        // Seed the HubPool some funds so it can send L1->L2 messages.
        await hubPool.connect(liquidityProvider).loadEthForL2Calls({ value: (0, utils_1.toWei)("1") });
        // Create an action that will send an L1->L2 tokens transfer and bundle. For this, create a relayer repayment bundle
        // and check that at it's finalization the L2 bridge contracts are called as expected.
        const { leaves, tree, tokensSendToL2 } = await (0, MerkleLib_utils_1.constructSingleChainTree)(usdc.address, 1, WORLD_CHAIN);
        await hubPool
            .connect(dataWorker)
            .proposeRootBundle([3117], 1, tree.getHexRoot(), consts.mockTreeRoot, consts.mockTreeRoot);
        await timer.setCurrentTime(Number(await timer.getCurrentTime()) + consts.refundProposalLiveness + 1);
        await hubPool.connect(dataWorker).executeRootBundle(...Object.values(leaves[0]), tree.getHexProof(leaves[0]));
        const l2Gas = await adapter.L2_GAS_LIMIT();
        (0, utils_1.expect)(opUSDCBridge.sendMessage).to.have.been.calledOnce;
        (0, utils_1.expect)(opUSDCBridge.sendMessage).to.have.been.calledWith(mockSpoke.address, tokensSendToL2, l2Gas);
    });
});
