// File: test/spells/Spell.sol



// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.21;

import "deployments/ETH_MAINNET.sol";

interface RootLike {
    function relyContract(address, address) external;
}

interface FileLike {
    function file(bytes32, address) external;
}

interface AuthLike {
    function rely(address) external;
    function deny(address) external;
}

interface PoolManagerLike {
    function removeLiquidityPool(uint64 poolId, bytes16 trancheId, address currency) external;
    function deployLiquidityPool(uint64 poolId, bytes16 trancheId, address currency) external returns (address);
    function getLiquidityPool(uint64 poolId, bytes16 trancheId, address currency) external returns (address);
}

interface LiquidityPoolLike {
    function poolId() external returns (uint64);
    function trancheId() external returns (bytes16);
    function asset() external returns (address);
}

// Spell to migrate the LiquidityPool factory contract
contract Spell is Addresses {
    bool public done;
    string public constant description = "Liquidity Pool Factory migration spell";

    address public constant LIQUIDITY_POOL_FACTORY_NEW = address(0x7f93eDB11d5Dc23F04C4E9382aa0d3F31E95BF2C);
    address public constant DEPRECATED_LIQUIDITY_POOL = address(0xa0872E8D2975483b2Ab4Afcee729133D8666F6f5);
    address public newLiquidityPool;

    address self;

    function cast() public {
        require(!done, "spell-already-cast");
        done = true;
        execute();
    }

    function execute() internal {
        self = address(this);

        // give spell required permissions
        RootLike root = RootLike(root);
        root.relyContract(LIQUIDITY_POOL_FACTORY_NEW, self);
        root.relyContract(poolManager, self);

        // spell magic
        migrateLiquidityPoolFactory();
        migrateLiquidityPool();

        // revoke all permissions from spell
        AuthLike(address(root)).deny(self);
        AuthLike(LIQUIDITY_POOL_FACTORY_NEW).deny(self);
        AuthLike(poolManager).deny(self);
    }

    function migrateLiquidityPoolFactory() internal {
        AuthLike(LIQUIDITY_POOL_FACTORY_NEW).rely(poolManager);
        AuthLike(LIQUIDITY_POOL_FACTORY_NEW).deny(deployer);
        FileLike(poolManager).file("liquidityPoolFactory", LIQUIDITY_POOL_FACTORY_NEW);
    }

    function migrateLiquidityPool() internal {
        LiquidityPoolLike deprectaedLP = LiquidityPoolLike(DEPRECATED_LIQUIDITY_POOL);
        address deprectaedLP_ = PoolManagerLike(poolManager).getLiquidityPool(
            deprectaedLP.poolId(), deprectaedLP.trancheId(), deprectaedLP.asset()
        );
        require(deprectaedLP_ == DEPRECATED_LIQUIDITY_POOL, "SPELL - unknown Liquidity Pool");
        // remove deprecated pool
        PoolManagerLike(poolManager).removeLiquidityPool(
            deprectaedLP.poolId(), deprectaedLP.trancheId(), deprectaedLP.asset()
        );
        // add new pool
        newLiquidityPool = PoolManagerLike(poolManager).deployLiquidityPool(
            deprectaedLP.poolId(), deprectaedLP.trancheId(), deprectaedLP.asset()
        );
    }
}

// File: deployments/ETH_MAINNET.sol



// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.21;

contract Addresses {
    address public root = address(0x498016d30Cd5f0db50d7ACE329C07313a0420502);
    address public investmentManager = address(0xbBF0AB988691dB1892ADaF7F0eF560Ca4c6DD73A);
    address public poolManager = address(0x78E9e622A57f70F1E0Ec652A4931E4e278e58142);
    address public gateway = address(0x634F036fE66579E901c7bA34e33DF422E37A0037);
    address public escrow = address(0xd595E1483c507E74E2E6A3dE8e7D08d8f6F74936);
    address public userEscrow= address(0x9fc3A3bcEdc1CaB14EfC1B7ef45dFBDd3d17c9d7);
    address public router = address(0x8174D5f12Ce682459864D8C081f9635012Ab51c2);
    address public trancheTokenFactory = address(0x4aEFE6CeFEd5D0A30679E41C0B3Fee6cbAa6ADf6);
    address public liquidityPoolFactory = address(0x77F48b2c942E6f3ac2232568d560e423c441386a);
    address public restrictionManagerFactory = address(0xf4D7F6919eF0B495a2551F7299324961F29aE7aC);
    address public pauseAdmin = address(0xce86472007Ea37a5d0208f8C1559A37530c8067C);
    address public delayedAdmin = address(0x2559998026796Ca6fd057f3aa66F2d6ecdEd9028);
    address public messages = address(0xAf9F6Ac63C057EB7F59b6Fae2c3d447191b58Ea5); 
    address public deployer = address(0x7270b20603FbB3dF0921381670fbd62b9991aDa4);
    address public admin = address(0xD9D30ab47c0f096b0AA67e9B8B1624504a63e7FD); // multisig

    // deployed LPs
    address public anemoyToken = address(0x30baA3BA9D7089fD8D020a994Db75D14CF7eC83b);
}