diff --git a/.env.EXAMPLE b/.env.EXAMPLE index 9a77dd8..ffd61a1 100644 --- a/.env.EXAMPLE +++ b/.env.EXAMPLE @@ -6,4 +6,6 @@ ETHERSCAN_API_KEY={$INSERT_KEY_HERE} POLYGON_RPC_URL=https://polygon-mainnet.g.alchemy.com/v2/{$INSERT_KEY_HERE} POLYGONSCAN_API_URL=https://api.polygonscan.com/api/ -POLYGONSCAN_API_KEY={$INSERT_KEY_HERE} \ No newline at end of file +POLYGONSCAN_API_KEY={$INSERT_KEY_HERE} + +NETWORK=MAINNET \ No newline at end of file diff --git a/scripts/constants/fraxtal-deployments.ts b/scripts/constants/fraxtal-deployments.ts new file mode 100644 index 0000000..a29dc4d --- /dev/null +++ b/scripts/constants/fraxtal-deployments.ts @@ -0,0 +1,3 @@ +export const DEVNET = "devnet"; +export const TESTNET = "testnet"; +export const MAINNET = "mainnet"; diff --git a/scripts/constants/fraxtal-devnet-l1.ts b/scripts/constants/fraxtal-devnet-l1.ts new file mode 100644 index 0000000..92fbc9d --- /dev/null +++ b/scripts/constants/fraxtal-devnet-l1.ts @@ -0,0 +1,9 @@ +export const FPI_ERC20 = "0x67218f66a84809201CfBa5c8b46dBd3aB95A42da"; +export const FPIS_ERC20 = "0xC0497C072d3015fd7D45893157bCDCC1BcfEb6b5"; +export const FRAX_ERC20 = "0xac3E018457B222d93114458476f3E3416Abbe38F"; +export const FXS_ERC20 = "0xbAFA44EFE7901E04E39Dad13167D089C559c1138"; +export const SFRXETH_ERC20 = "0x56390acF12bce9675ab3922060D8d955149BE286"; +export const FRXETH_ERC20 = "0xB1C4e5a15544f005166880749C46D35a00916462"; +export const FRXETH_MINTER = "0x80f1C4F5CD94D49e98D0a975690796f1E8C0379e"; +export const FRXBTC_ERC20 = "0x3fe0150F6Daa6a54C585f85f0e78d665532e5b74"; +export const SFRAX_ERC20 = "0x1D348307745645b91c49716Fae22Ad5d4CC0b94a"; diff --git a/scripts/constants/fraxtal-devnet-l2.ts b/scripts/constants/fraxtal-devnet-l2.ts new file mode 100644 index 0000000..8b27e1f --- /dev/null +++ b/scripts/constants/fraxtal-devnet-l2.ts @@ -0,0 +1,8 @@ +export const FRAXCHAIN_ADMIN = "0x8b1E899ec5d51387a41Ee68261149F7d3Dfd7160"; +export const PROXY_ADMIN = "0xfC00000000000000000000000000000000000009"; +export const L2_STANDARD_BRIDGE = "0x4200000000000000000000000000000000000010"; + +export const COMPTROLLER = "0x8b1E899ec5d51387a41Ee68261149F7d3Dfd7160"; + +// Fraxswap-specific +export const FRAXSWAP_FACTORY = "0x0000000000000000000000000000000000000000"; diff --git a/scripts/constants/fraxtal-mainnet.ts b/scripts/constants/fraxtal-mainnet.ts new file mode 100644 index 0000000..58f071e --- /dev/null +++ b/scripts/constants/fraxtal-mainnet.ts @@ -0,0 +1,8 @@ +export const FRAXCHAIN_ADMIN = "0xC4EB45d80DC1F079045E75D5d55de8eD1c1090E6"; +export const PROXY_ADMIN = "0xfC00000000000000000000000000000000000009"; +export const L2_STANDARD_BRIDGE = "0x4200000000000000000000000000000000000010"; + +export const COMPTROLLER = "0xC4EB45d80DC1F079045E75D5d55de8eD1c1090E6"; + +// Fraxswap-specific +export const FRAXSWAP_FACTORY = "0x0000000000000000000000000000000000000000"; diff --git a/scripts/constants/fraxtal-proxies.ts b/scripts/constants/fraxtal-proxies.ts new file mode 100644 index 0000000..07c6903 --- /dev/null +++ b/scripts/constants/fraxtal-proxies.ts @@ -0,0 +1,8 @@ +export const FRAX_PROXY = "0xFc00000000000000000000000000000000000001"; +export const FXS_PROXY = "0xFc00000000000000000000000000000000000002"; +export const FPI_PROXY = "0xFc00000000000000000000000000000000000003"; +export const FPIS_PROXY = "0xfc00000000000000000000000000000000000004"; +export const SFRXETH_PROXY = "0xFC00000000000000000000000000000000000005"; +export const WFRXETH_PROXY = "0xFC00000000000000000000000000000000000006"; +export const STANDARD_BRIDGE_PROXY = "0x4200000000000000000000000000000000000010"; +export const ERC20_FACTORY_PROXY = "0x4200000000000000000000000000000000000012"; diff --git a/scripts/constants/fraxtal-testnet.ts b/scripts/constants/fraxtal-testnet.ts new file mode 100644 index 0000000..0dea446 --- /dev/null +++ b/scripts/constants/fraxtal-testnet.ts @@ -0,0 +1,8 @@ +export const FRAXCHAIN_ADMIN = "0x8b1E899ec5d51387a41Ee68261149F7d3Dfd7160"; +export const PROXY_ADMIN = "0xfC00000000000000000000000000000000000007"; +export const L2_STANDARD_BRIDGE = "0x4200000000000000000000000000000000000010"; + +export const COMPTROLLER = "0x012fcFb933b9a4335B1BCC836e6a9a475146beBd"; + +// Fraxswap-specific +export const FRAXSWAP_FACTORY = "0x0000000000000000000000000000000000000000"; diff --git a/scripts/constants/holesky.ts b/scripts/constants/holesky.ts new file mode 100644 index 0000000..2f6e6af --- /dev/null +++ b/scripts/constants/holesky.ts @@ -0,0 +1,7 @@ +export const FPI_ERC20 = "0xfBCB0F967817c924f83e26e04F0FB28ED4d6276F"; +export const FPIS_ERC20 = "0x0363a32D18c25a3FD19a0d00B02106C03d8b8182"; +export const FRAX_ERC20 = "0x0304A365C0fbb4b1Ad423887861b9b69a5f0c00E"; +export const FXS_ERC20 = "0x4e7300F74F59AFaEcCdc0d434758Df9be238F0BF"; +export const SFRXETH_ERC20 = "0xa63f56985F9C7F3bc9fFc5685535649e0C1a55f3"; +export const FRXETH_ERC20 = "0x17845EA6a9BfD2caF1b9E558948BB4999dF2656e"; +export const FRXETH_MINTER = "0x5E8422345238F34275888049021821E8E08CAa1f"; diff --git a/scripts/constants/index.ts b/scripts/constants/index.ts index 7634344..368da7e 100644 --- a/scripts/constants/index.ts +++ b/scripts/constants/index.ts @@ -1 +1,8 @@ export * as Mainnet from "./mainnet"; +export * as Holesky from "./holesky"; +export * as FraxtalDeployment from "./fraxtal-deployments"; +export * as FraxtalL1Devnet from "./fraxtal-devnet-l1"; +export * as FraxtalL2Devnet from "./fraxtal-devnet-l2"; +export * as FraxtalTestnet from "./fraxtal-testnet"; +export * as FraxtalMainnet from "./fraxtal-mainnet"; +export * as FraxtalProxies from "./fraxtal-proxies"; diff --git a/scripts/constants/mainnet.ts b/scripts/constants/mainnet.ts index 9ca8682..9c3c5be 100644 --- a/scripts/constants/mainnet.ts +++ b/scripts/constants/mainnet.ts @@ -128,11 +128,11 @@ export const AUCTION_20241231 = "0xc9aa98788a675FF0846E8856cb83F19452f3b0c8"; export const ORACLE_20241231 = "0x08a0748cF885F46e20fA30A50a035808eab293D3"; export const CURVE_20241231_MAINNET_POOL = "0x6307E6688819951Cf8D6B6066018243D2496952F"; export const CURVE_20241231_ARBITRUM_POOL = "0xE920eEdAff6c3BEd1Ef61010B64d46986634E908"; -export const CURVE_20241231_ARBITRUM_GAUGE = "0x05824d6d4de8a0ede4e12b98387a4f035a67ee68"; +export const CURVE_20241231_ARBITRUM_GAUGE = "0x05824D6D4DE8A0ede4e12b98387A4f035a67ee68"; // December 31, 2026 expiry export const FXB_20261231 = "0x76237BCfDbe8e06FB774663add96216961df4ff3"; export const AUCTION_20261231 = "0x63981f5E690eaF7E8795c42832664e8848F532fB"; export const ORACLE_20261231 = "0x2ec5D1C13fEF1C7029eE329a1D31B2180c9b3707"; export const CURVE_20261231_MAINNET_POOL = "0xe035e27A8eD6842b478933820f90093D205F7098"; export const CURVE_20261231_ARBITRUM_POOL = "0x946adc524BD312D036776798c46ceDD948DD0A0f"; -export const CURVE_20261231_ARBITRUM_GAUGE = "0xa2617a26f9f528fa7b0e47fc2e66fcc04c6682e9"; +export const CURVE_20261231_ARBITRUM_GAUGE = "0xa2617A26f9f528fa7B0E47fc2e66FcC04C6682E9"; diff --git a/scripts/generateConstants.ts b/scripts/generateConstants.ts index f8b5e9b..d9bec4b 100644 --- a/scripts/generateConstants.ts +++ b/scripts/generateConstants.ts @@ -23,7 +23,11 @@ import { TestBase } from "forge-std/Test.sol"; async function handleSingleNetwork(networkName, constants) { const constantString = Object.entries(constants) .map(([key, value]) => { - return ` address internal constant ${key} = ${value};`; + if ((value as string).startsWith("0x")) { + return ` address internal constant ${key} = ${value};`; + } + + return ` string internal constant ${key} = "${value}";`; }) .join("\n"); diff --git a/scripts/someNodeScript.ts b/scripts/someNodeScript.ts deleted file mode 100644 index 329f221..0000000 --- a/scripts/someNodeScript.ts +++ /dev/null @@ -1 +0,0 @@ -// placeholder \ No newline at end of file diff --git a/src/Constants.sol b/src/Constants.sol index 01fb0aa..3fecd74 100644 --- a/src/Constants.sol +++ b/src/Constants.sol @@ -230,3 +230,66 @@ abstract contract Helper is TestBase { vm.label(0xa2617A26f9f528fa7B0E47fc2e66FcC04C6682E9, "Constants.CURVE_20261231_ARBITRUM_GAUGE"); } } + +library Holesky { + address internal constant FPI_ERC20 = 0xfBCB0F967817c924f83e26e04F0FB28ED4d6276F; + address internal constant FPIS_ERC20 = 0x0363a32D18c25a3FD19a0d00B02106C03d8b8182; + address internal constant FRAX_ERC20 = 0x0304A365C0fbb4b1Ad423887861b9b69a5f0c00E; + address internal constant FXS_ERC20 = 0x4e7300F74F59AFaEcCdc0d434758Df9be238F0BF; + address internal constant SFRXETH_ERC20 = 0xa63f56985F9C7F3bc9fFc5685535649e0C1a55f3; + address internal constant FRXETH_ERC20 = 0x17845EA6a9BfD2caF1b9E558948BB4999dF2656e; + address internal constant FRXETH_MINTER = 0x5E8422345238F34275888049021821E8E08CAa1f; +} + +library FraxtalDeployment { + string internal constant DEVNET = "devnet"; + string internal constant TESTNET = "testnet"; + string internal constant MAINNET = "mainnet"; +} + +library FraxtalL1Devnet { + address internal constant FPI_ERC20 = 0x67218f66a84809201CfBa5c8b46dBd3aB95A42da; + address internal constant FPIS_ERC20 = 0xC0497C072d3015fd7D45893157bCDCC1BcfEb6b5; + address internal constant FRAX_ERC20 = 0xac3E018457B222d93114458476f3E3416Abbe38F; + address internal constant FXS_ERC20 = 0xbAFA44EFE7901E04E39Dad13167D089C559c1138; + address internal constant SFRXETH_ERC20 = 0x56390acF12bce9675ab3922060D8d955149BE286; + address internal constant FRXETH_ERC20 = 0xB1C4e5a15544f005166880749C46D35a00916462; + address internal constant FRXETH_MINTER = 0x80f1C4F5CD94D49e98D0a975690796f1E8C0379e; + address internal constant FRXBTC_ERC20 = 0x3fe0150F6Daa6a54C585f85f0e78d665532e5b74; + address internal constant SFRAX_ERC20 = 0x1D348307745645b91c49716Fae22Ad5d4CC0b94a; +} + +library FraxtalL2Devnet { + address internal constant FRAXCHAIN_ADMIN = 0x8b1E899ec5d51387a41Ee68261149F7d3Dfd7160; + address internal constant PROXY_ADMIN = 0xfC00000000000000000000000000000000000009; + address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010; + address internal constant COMPTROLLER = 0x8b1E899ec5d51387a41Ee68261149F7d3Dfd7160; + address internal constant FRAXSWAP_FACTORY = 0x0000000000000000000000000000000000000000; +} + +library FraxtalTestnet { + address internal constant FRAXCHAIN_ADMIN = 0x8b1E899ec5d51387a41Ee68261149F7d3Dfd7160; + address internal constant PROXY_ADMIN = 0xfC00000000000000000000000000000000000007; + address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010; + address internal constant COMPTROLLER = 0x012fcFb933b9a4335B1BCC836e6a9a475146beBd; + address internal constant FRAXSWAP_FACTORY = 0x0000000000000000000000000000000000000000; +} + +library FraxtalMainnet { + address internal constant FRAXCHAIN_ADMIN = 0xC4EB45d80DC1F079045E75D5d55de8eD1c1090E6; + address internal constant PROXY_ADMIN = 0xfC00000000000000000000000000000000000009; + address internal constant L2_STANDARD_BRIDGE = 0x4200000000000000000000000000000000000010; + address internal constant COMPTROLLER = 0xC4EB45d80DC1F079045E75D5d55de8eD1c1090E6; + address internal constant FRAXSWAP_FACTORY = 0x0000000000000000000000000000000000000000; +} + +library FraxtalProxies { + address internal constant FRAX_PROXY = 0xFc00000000000000000000000000000000000001; + address internal constant FXS_PROXY = 0xFc00000000000000000000000000000000000002; + address internal constant FPI_PROXY = 0xFc00000000000000000000000000000000000003; + address internal constant FPIS_PROXY = 0xfc00000000000000000000000000000000000004; + address internal constant SFRXETH_PROXY = 0xFC00000000000000000000000000000000000005; + address internal constant WFRXETH_PROXY = 0xFC00000000000000000000000000000000000006; + address internal constant STANDARD_BRIDGE_PROXY = 0x4200000000000000000000000000000000000010; + address internal constant ERC20_FACTORY_PROXY = 0x4200000000000000000000000000000000000012; +} diff --git a/src/contracts/core/FraxswapFactory.sol b/src/contracts/core/FraxswapFactory.sol index 0109a17..d699cc5 100644 --- a/src/contracts/core/FraxswapFactory.sol +++ b/src/contracts/core/FraxswapFactory.sol @@ -30,8 +30,9 @@ contract FraxswapFactory { error ZeroAddress(); error PairExists(); - constructor(address _feeToSetter) { - feeToSetter = _feeToSetter; + constructor(address _owner) { + feeToSetter = _owner; + feeTo = _owner; } ///@notice Throws if called by any account other than the feeToSetter. diff --git a/src/script/DeployCounter.s.sol b/src/script/DeployCounter.s.sol deleted file mode 100644 index 9494038..0000000 --- a/src/script/DeployCounter.s.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: ISC -pragma solidity ^0.8.19; - -import { BaseScript } from "frax-std/BaseScript.sol"; -import { console } from "frax-std/FraxTest.sol"; -// import { Counter } from "../contracts/Counter.sol"; - -// // This is a free function that can be imported and used in tests or other scripts -// function deployCounter() returns (address _address) { -// Counter _counter = new Counter(); -// _address = address(_counter); -// } - -// // Run this with source .env && forge script --broadcast --rpc-url $MAINNET_URL DeployCounter.s.sol -// contract DeployCounter is BaseScript { -// function run() public broadcaster { -// address _address = deployCounter(); -// console.log("Deployed Counter at address: ", _address); -// } -// } diff --git a/src/script/DeployFraxswapFactory.s.sol b/src/script/DeployFraxswapFactory.s.sol new file mode 100644 index 0000000..9b24ba2 --- /dev/null +++ b/src/script/DeployFraxswapFactory.s.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: ISC +pragma solidity ^0.8.19; + +import { FraxtalScript } from "./FraxtalScript.s.sol"; +import { console } from "frax-std/FraxTest.sol"; +import { FraxswapFactory } from "src/contracts/core/FraxswapFactory.sol"; +import "../Constants.sol" as Constants; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; + +function deployFraxswapFactory(address _owner) returns (FraxswapFactory iFraxswapFactory, address fraxswapFactory) { + iFraxswapFactory = new FraxswapFactory({ _owner: _owner }); + fraxswapFactory = address(iFraxswapFactory); +} + +contract DeployFraxswapFactory is FraxtalScript { + function run() public broadcaster { + address owner; + if (Strings.equal(network, Constants.FraxtalDeployment.DEVNET)) { + owner = Constants.FraxtalL2Devnet.COMPTROLLER; + } else if (Strings.equal(network, Constants.FraxtalDeployment.TESTNET)) { + owner = Constants.FraxtalTestnet.COMPTROLLER; + } else if (Strings.equal(network, Constants.FraxtalDeployment.MAINNET)) { + owner = Constants.FraxtalMainnet.COMPTROLLER; + } + require(owner != address(0), "FraxswapFactory not set in network"); + + (, address fraxswapFactory) = deployFraxswapFactory({ _owner: owner }); + console.log("FraxswapFactory deployed to: ", fraxswapFactory); + } +} diff --git a/src/script/DeployFraxswapRouter.s.sol b/src/script/DeployFraxswapRouter.s.sol new file mode 100644 index 0000000..6d40825 --- /dev/null +++ b/src/script/DeployFraxswapRouter.s.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: ISC +pragma solidity ^0.8.19; + +import { FraxtalScript } from "./FraxtalScript.s.sol"; +import { console } from "frax-std/FraxTest.sol"; +import { FraxswapRouter } from "src/contracts/periphery/FraxswapRouter.sol"; +import "../Constants.sol" as Constants; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; + +function deployFraxswapRouter( + address _factory, + address _WETH +) returns (FraxswapRouter iFraxswapRouter, address fraxswapRouter) { + iFraxswapRouter = new FraxswapRouter({ _factory: _factory, _WETH: _WETH }); + fraxswapRouter = address(iFraxswapRouter); +} + +contract DeployFraxswapRouter is FraxtalScript { + function run() external broadcaster { + address fraxswapFactory; + if (Strings.equal(network, Constants.FraxtalDeployment.DEVNET)) { + fraxswapFactory = Constants.FraxtalL2Devnet.FRAXSWAP_FACTORY; + } else if (Strings.equal(network, Constants.FraxtalDeployment.TESTNET)) { + fraxswapFactory = Constants.FraxtalTestnet.FRAXSWAP_FACTORY; + } else if (Strings.equal(network, Constants.FraxtalDeployment.MAINNET)) { + fraxswapFactory = Constants.FraxtalMainnet.FRAXSWAP_FACTORY; + } + require(fraxswapFactory != address(0), "FraxswapFactory not set in network"); + + deployFraxswapRouter({ _factory: fraxswapFactory, _WETH: Constants.FraxtalProxies.WFRXETH_PROXY }); + } +} diff --git a/src/script/DeployFraxswapRouterMultihop.s.sol b/src/script/DeployFraxswapRouterMultihop.s.sol new file mode 100644 index 0000000..8498405 --- /dev/null +++ b/src/script/DeployFraxswapRouterMultihop.s.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: ISC +pragma solidity ^0.8.19; + +import { FraxtalScript } from "./FraxtalScript.s.sol"; +import { console } from "frax-std/FraxTest.sol"; +import { FraxswapRouterMultihop } from "src/contracts/periphery/FraxswapRouterMultihop.sol"; +import { IWETH } from "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol"; +import "../Constants.sol" as Constants; + +function deployFraxswapRouterMultihop( + address _WETH9, + address _FRAX, + bool _CHECK_AMOUNTOUT_IN_ROUTER +) returns (FraxswapRouterMultihop iFraxswapRouterMultihop, address fraxswapRouterMultihop) { + iFraxswapRouterMultihop = new FraxswapRouterMultihop({ + _WETH9: IWETH(_WETH9), + _FRAX: _FRAX, + _CHECK_AMOUNTOUT_IN_ROUTER: _CHECK_AMOUNTOUT_IN_ROUTER + }); + fraxswapRouterMultihop = address(iFraxswapRouterMultihop); +} + +contract DeployFraxswapRouterMultihop is FraxtalScript { + function run() public broadcaster { + (, address fraxswapRouterMultihop) = deployFraxswapRouterMultihop({ + _WETH9: Constants.FraxtalProxies.WFRXETH_PROXY, + _FRAX: Constants.FraxtalProxies.FRAX_PROXY, + _CHECK_AMOUNTOUT_IN_ROUTER: true + }); + console.log("FraxswapRouterMultihop deployed to: ", fraxswapRouterMultihop); + } +} diff --git a/src/script/FraxtalScript.s.sol b/src/script/FraxtalScript.s.sol new file mode 100644 index 0000000..de7e6c4 --- /dev/null +++ b/src/script/FraxtalScript.s.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: ISC +pragma solidity >=0.8.0; + +import { BaseScript } from "frax-std/BaseScript.sol"; +import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; +import "../Constants.sol" as Constants; + +// @dev: Safety to ensure script is deployed to a fraxtal chain +contract FraxtalScript is BaseScript { + string internal network; + + function setUp() public virtual override { + BaseScript.setUp(); + network = vm.envString("NETWORK"); + + if ( + !Strings.equal(network, Constants.FraxtalDeployment.DEVNET) && + !Strings.equal(network, Constants.FraxtalDeployment.TESTNET) && + !Strings.equal(network, Constants.FraxtalDeployment.MAINNET) + ) { + revert("NETWORK env variable must be either 'devnet' or 'testnet' or 'mainnet'"); + } + } +}