- CCIP/trustless bridge contracts, GRU tokens, DEX/PMM tests, reserve vault. - Token-aggregation service routes, planner, chain config, relay env templates. - Config snapshots and multi-chain deployment markdown updates. - gitignore services/btc-intake/dist/ (tsc output); do not track dist. Run forge build && forge test before deploy (large solc graph). Made-with: Cursor
142 lines
8.1 KiB
Solidity
142 lines
8.1 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.19;
|
|
|
|
import {Script, console} from "forge-std/Script.sol";
|
|
import "../../../contracts/bridge/trustless/EnhancedSwapRouterV2.sol";
|
|
import "../../../contracts/bridge/trustless/RouteTypesV2.sol";
|
|
import "../../../contracts/bridge/trustless/pilot/Chain138PilotDexVenues.sol";
|
|
|
|
contract DeployChain138PilotDexVenues is Script {
|
|
address constant CHAIN138_WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
|
address constant CHAIN138_USDT = 0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1;
|
|
address constant CHAIN138_USDC = 0x71D6687F38b93CCad569Fa6352c876eea967201b;
|
|
address constant LIVE_ROUTER_V2 = 0xF1c93F54A5C2fc0d7766Ccb0Ad8f157DFB4C99Ce;
|
|
|
|
uint24 constant UNISWAP_FEE = 3000;
|
|
uint256 constant BALANCER_FEE_BPS = 30;
|
|
uint256 constant CURVE_FEE_BPS = 4;
|
|
uint256 constant ONE_INCH_FEE_BPS = 35;
|
|
|
|
bytes32 constant BALANCER_WETH_USDT_POOL_ID = keccak256("chain138-pilot-balancer-weth-usdt");
|
|
bytes32 constant BALANCER_WETH_USDC_POOL_ID = keccak256("chain138-pilot-balancer-weth-usdc");
|
|
|
|
uint256 constant WETH_PAIR_WETH_AMOUNT = 100 ether;
|
|
uint256 constant WETH_PAIR_STABLE_AMOUNT = 210_000 * 1e6;
|
|
uint256 constant CURVE_STABLE_AMOUNT = 500_000 * 1e6;
|
|
|
|
function run() external {
|
|
require(block.chainid == 138, "DeployChain138PilotDexVenues: Chain 138 only");
|
|
|
|
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
|
|
address deployer = vm.addr(deployerPrivateKey);
|
|
address payable routerV2 = payable(vm.envOr("ENHANCED_SWAP_ROUTER_V2_ADDRESS", LIVE_ROUTER_V2));
|
|
|
|
vm.startBroadcast(deployerPrivateKey);
|
|
|
|
Chain138PilotUniswapV3Router uniswapRouter = new Chain138PilotUniswapV3Router();
|
|
Chain138PilotBalancerVault balancerVault = new Chain138PilotBalancerVault();
|
|
Chain138PilotCurve3Pool curve3Pool = new Chain138PilotCurve3Pool(CHAIN138_USDT, CHAIN138_USDC, address(0), CURVE_FEE_BPS);
|
|
Chain138PilotOneInchAggregationRouter oneInchRouter = new Chain138PilotOneInchAggregationRouter();
|
|
|
|
uint256 totalUsdtRequired = (WETH_PAIR_STABLE_AMOUNT * 3) + CURVE_STABLE_AMOUNT;
|
|
uint256 totalUsdcRequired = (WETH_PAIR_STABLE_AMOUNT * 3) + CURVE_STABLE_AMOUNT;
|
|
uint256 totalWethRequired = WETH_PAIR_WETH_AMOUNT * 6;
|
|
|
|
_ensureMintedStable(CHAIN138_USDT, deployer, totalUsdtRequired);
|
|
_ensureMintedStable(CHAIN138_USDC, deployer, totalUsdcRequired);
|
|
_ensureWrappedWeth(deployer, totalWethRequired);
|
|
|
|
_approveToken(CHAIN138_WETH, address(uniswapRouter), WETH_PAIR_WETH_AMOUNT * 2);
|
|
_approveToken(CHAIN138_USDT, address(uniswapRouter), WETH_PAIR_STABLE_AMOUNT);
|
|
_approveToken(CHAIN138_USDC, address(uniswapRouter), WETH_PAIR_STABLE_AMOUNT);
|
|
uniswapRouter.seedPair(CHAIN138_WETH, CHAIN138_USDT, UNISWAP_FEE, WETH_PAIR_WETH_AMOUNT, WETH_PAIR_STABLE_AMOUNT);
|
|
uniswapRouter.seedPair(CHAIN138_WETH, CHAIN138_USDC, UNISWAP_FEE, WETH_PAIR_WETH_AMOUNT, WETH_PAIR_STABLE_AMOUNT);
|
|
|
|
_approveToken(CHAIN138_WETH, address(balancerVault), WETH_PAIR_WETH_AMOUNT * 2);
|
|
_approveToken(CHAIN138_USDT, address(balancerVault), WETH_PAIR_STABLE_AMOUNT);
|
|
_approveToken(CHAIN138_USDC, address(balancerVault), WETH_PAIR_STABLE_AMOUNT);
|
|
balancerVault.seedPool(BALANCER_WETH_USDT_POOL_ID, CHAIN138_WETH, CHAIN138_USDT, WETH_PAIR_WETH_AMOUNT, WETH_PAIR_STABLE_AMOUNT, BALANCER_FEE_BPS);
|
|
balancerVault.seedPool(BALANCER_WETH_USDC_POOL_ID, CHAIN138_WETH, CHAIN138_USDC, WETH_PAIR_WETH_AMOUNT, WETH_PAIR_STABLE_AMOUNT, BALANCER_FEE_BPS);
|
|
|
|
_approveToken(CHAIN138_USDT, address(curve3Pool), CURVE_STABLE_AMOUNT);
|
|
_approveToken(CHAIN138_USDC, address(curve3Pool), CURVE_STABLE_AMOUNT);
|
|
curve3Pool.fund(CURVE_STABLE_AMOUNT, CURVE_STABLE_AMOUNT, 0);
|
|
|
|
_approveToken(CHAIN138_WETH, address(oneInchRouter), WETH_PAIR_WETH_AMOUNT * 2);
|
|
_approveToken(CHAIN138_USDT, address(oneInchRouter), WETH_PAIR_STABLE_AMOUNT);
|
|
_approveToken(CHAIN138_USDC, address(oneInchRouter), WETH_PAIR_STABLE_AMOUNT);
|
|
oneInchRouter.seedRoute(CHAIN138_WETH, CHAIN138_USDT, WETH_PAIR_WETH_AMOUNT, WETH_PAIR_STABLE_AMOUNT, ONE_INCH_FEE_BPS);
|
|
oneInchRouter.seedRoute(CHAIN138_WETH, CHAIN138_USDC, WETH_PAIR_WETH_AMOUNT, WETH_PAIR_STABLE_AMOUNT, ONE_INCH_FEE_BPS);
|
|
|
|
if (routerV2 != address(0)) {
|
|
EnhancedSwapRouterV2 router = EnhancedSwapRouterV2(routerV2);
|
|
bytes memory uniswapProviderData = abi.encode(bytes(""), UNISWAP_FEE, address(uniswapRouter), false);
|
|
bytes memory balancerUsdtProviderData = abi.encode(BALANCER_WETH_USDT_POOL_ID);
|
|
bytes memory balancerUsdcProviderData = abi.encode(BALANCER_WETH_USDC_POOL_ID);
|
|
bytes memory curveProviderData = abi.encode(int128(0), int128(1), false);
|
|
bytes memory oneInchProviderData = abi.encode(address(oneInchRouter), address(oneInchRouter), bytes(""));
|
|
|
|
_setBidirectionalRoute(router, CHAIN138_WETH, CHAIN138_USDT, RouteTypesV2.Provider.UniswapV3, address(uniswapRouter), uniswapProviderData);
|
|
_setBidirectionalRoute(router, CHAIN138_WETH, CHAIN138_USDC, RouteTypesV2.Provider.UniswapV3, address(uniswapRouter), uniswapProviderData);
|
|
|
|
_setBidirectionalRoute(router, CHAIN138_WETH, CHAIN138_USDT, RouteTypesV2.Provider.Balancer, address(balancerVault), balancerUsdtProviderData);
|
|
_setBidirectionalRoute(router, CHAIN138_WETH, CHAIN138_USDC, RouteTypesV2.Provider.Balancer, address(balancerVault), balancerUsdcProviderData);
|
|
|
|
_setBidirectionalRoute(router, CHAIN138_USDT, CHAIN138_USDC, RouteTypesV2.Provider.Curve, address(curve3Pool), curveProviderData);
|
|
|
|
_setBidirectionalRoute(router, CHAIN138_WETH, CHAIN138_USDT, RouteTypesV2.Provider.OneInch, address(oneInchRouter), oneInchProviderData);
|
|
_setBidirectionalRoute(router, CHAIN138_WETH, CHAIN138_USDC, RouteTypesV2.Provider.OneInch, address(oneInchRouter), oneInchProviderData);
|
|
router.setProviderEnabled(RouteTypesV2.Provider.OneInch, true);
|
|
}
|
|
|
|
vm.stopBroadcast();
|
|
|
|
console.log("CHAIN138_PILOT_UNISWAP_V3_ROUTER:", address(uniswapRouter));
|
|
console.log("CHAIN138_PILOT_UNISWAP_V3_QUOTER:", address(uniswapRouter));
|
|
console.log("CHAIN138_PILOT_BALANCER_VAULT:", address(balancerVault));
|
|
console.log("CHAIN138_PILOT_BALANCER_WETH_USDT_POOL_ID:");
|
|
console.logBytes32(BALANCER_WETH_USDT_POOL_ID);
|
|
console.log("CHAIN138_PILOT_BALANCER_WETH_USDC_POOL_ID:");
|
|
console.logBytes32(BALANCER_WETH_USDC_POOL_ID);
|
|
console.log("CHAIN138_PILOT_CURVE_3POOL:", address(curve3Pool));
|
|
console.log("CHAIN138_PILOT_ONEINCH_ROUTER:", address(oneInchRouter));
|
|
}
|
|
|
|
function _ensureMintedStable(address token, address deployer, uint256 requiredBalance) internal {
|
|
uint256 currentBalance = IERC20(token).balanceOf(deployer);
|
|
if (currentBalance >= requiredBalance) {
|
|
return;
|
|
}
|
|
uint256 delta = requiredBalance - currentBalance;
|
|
(bool ok,) = token.call(abi.encodeWithSignature("mint(address,uint256)", deployer, delta));
|
|
require(ok, "DeployChain138PilotDexVenues: stable mint failed");
|
|
}
|
|
|
|
function _ensureWrappedWeth(address deployer, uint256 requiredBalance) internal {
|
|
uint256 currentBalance = IERC20(CHAIN138_WETH).balanceOf(deployer);
|
|
if (currentBalance >= requiredBalance) {
|
|
return;
|
|
}
|
|
uint256 delta = requiredBalance - currentBalance;
|
|
(bool ok,) = CHAIN138_WETH.call{value: delta}(abi.encodeWithSignature("deposit()"));
|
|
require(ok, "DeployChain138PilotDexVenues: WETH deposit failed");
|
|
}
|
|
|
|
function _approveToken(address token, address spender, uint256 amount) internal {
|
|
IERC20(token).approve(spender, 0);
|
|
IERC20(token).approve(spender, amount);
|
|
}
|
|
|
|
function _setBidirectionalRoute(
|
|
EnhancedSwapRouterV2 router,
|
|
address tokenA,
|
|
address tokenB,
|
|
RouteTypesV2.Provider provider,
|
|
address target,
|
|
bytes memory providerData
|
|
) internal {
|
|
router.setProviderRoute(tokenA, tokenB, provider, target, providerData, true);
|
|
router.setProviderRoute(tokenB, tokenA, provider, target, providerData, true);
|
|
}
|
|
}
|