From 137ce7675b3aac39cc1e0075dc06b0d08a298839 Mon Sep 17 00:00:00 2001 From: FabienC Date: Wed, 30 Apr 2025 13:09:51 +0300 Subject: [PATCH 1/4] refactor: remove unused paUSD --- test/Base.t.sol | 3 --- test/helpers/Deploys.sol | 1 - 2 files changed, 4 deletions(-) diff --git a/test/Base.t.sol b/test/Base.t.sol index 2f132e8..a9e9592 100644 --- a/test/Base.t.sol +++ b/test/Base.t.sol @@ -22,8 +22,6 @@ abstract contract Base_Test is Test, Deploys, Assertions, Defaults, Utils { // Deploy PAR token contract. par = _deployERC20Mock("PAR", "PAR", 18); - // Deploy paUSD token contract. - paUSD = _deployERC20Mock("paUSD", "paUSD", 18); // Deploy PRL token contract. prl = _deployERC20Mock("prl", "PRL", 18); // Deploy BPT token contract. @@ -62,7 +60,6 @@ abstract contract Base_Test is Test, Deploys, Assertions, Defaults, Utils { vm.deal({ account: user.addr, newBalance: INITIAL_BALANCE }); if (setTokenBalance) { par.mint(user.addr, INITIAL_BALANCE); - paUSD.mint(user.addr, INITIAL_BALANCE); prl.mint(user.addr, INITIAL_BALANCE); weth.mint(user.addr, INITIAL_BALANCE); } diff --git a/test/helpers/Deploys.sol b/test/helpers/Deploys.sol index 8e99edb..ff708da 100644 --- a/test/helpers/Deploys.sol +++ b/test/helpers/Deploys.sol @@ -40,7 +40,6 @@ abstract contract Deploys is Test { ERC20Mock internal par; ERC20Mock internal prl; - ERC20Mock internal paUSD; ERC20Mock internal bpt; ERC20Mock internal auraBpt; From 70cc54eb120248c8d9553570aed93a29ae4a22f9 Mon Sep 17 00:00:00 2001 From: FabienC Date: Wed, 30 Apr 2025 13:10:06 +0300 Subject: [PATCH 2/4] fix: balancer mock --- test/mocks/BalancerV3RouterMock.sol | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/mocks/BalancerV3RouterMock.sol b/test/mocks/BalancerV3RouterMock.sol index 36eee35..ffa4cc0 100644 --- a/test/mocks/BalancerV3RouterMock.sol +++ b/test/mocks/BalancerV3RouterMock.sol @@ -11,9 +11,11 @@ contract BalancerV3RouterMock is IBalancerV3Router { ERC20Mock public bpt; IPermit2 public permit2; uint256 ratio = 1e18; + bool isReversedBalancerPair; constructor(address[2] memory _tokens, address _bpt, address _permit2) { tokens = _tokens; + isReversedBalancerPair = _tokens[0] > _tokens[1]; bpt = ERC20Mock(_bpt); permit2 = IPermit2(_permit2); } @@ -36,8 +38,12 @@ contract BalancerV3RouterMock is IBalancerV3Router { { uint256 amountIn0 = (maxAmountsIn[0] * ratio) / 1e18; uint256 amountIn1 = (maxAmountsIn[1] * ratio) / 1e18; - permit2.transferFrom(msg.sender, address(this), uint160(amountIn0), tokens[0]); - permit2.transferFrom(msg.sender, address(this), uint160(amountIn1), tokens[1]); + permit2.transferFrom( + msg.sender, address(this), uint160(amountIn0), isReversedBalancerPair ? tokens[1] : tokens[0] + ); + permit2.transferFrom( + msg.sender, address(this), uint160(amountIn1), isReversedBalancerPair ? tokens[0] : tokens[1] + ); bpt.mint(msg.sender, exactBptAmountOut); amountsIn = new uint256[](2); amountsIn[0] = amountIn0; From dd944c1d447a7ca8ea97d6f0ce7ca2f4ba66e445 Mon Sep 17 00:00:00 2001 From: FabienC Date: Wed, 30 Apr 2025 13:11:41 +0300 Subject: [PATCH 3/4] refactor: deployment types and file --- bun.lockb | Bin 208005 -> 214729 bytes deploy/config/arbiSepolia/config.json | 5 +-- deploy/config/sepolia/config.json | 6 +-- deploy/scripts/fees/MainFeeDistributor.ts | 4 +- deploy/scripts/fees/SideChainFeeCollector.ts | 4 +- .../RewardMerkleDistributor.ts | 3 +- deploy/scripts/sprl/sPRL1.ts | 4 +- deploy/scripts/sprl/sPRL2.ts | 38 +++++++++--------- deploy/utils/index.ts | 6 --- deploy/utils/types.ts | 7 ++-- package.json | 3 +- 11 files changed, 33 insertions(+), 47 deletions(-) diff --git a/bun.lockb b/bun.lockb index d047fc1be6bc78c55c854809dd2fbf7242bb89fb..90390e69cea5febeb0892ce53fce983ddad324df 100755 GIT binary patch delta 48502 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 delta 44173 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 BJ;DG0 diff --git a/deploy/config/arbiSepolia/config.json b/deploy/config/arbiSepolia/config.json index 27fe1db..fa1716c 100644 --- a/deploy/config/arbiSepolia/config.json +++ b/deploy/config/arbiSepolia/config.json @@ -6,7 +6,6 @@ }, "tokens": { "prl": "0x0F4DE51EF1E7611aD0A9181F2d62B9c8408EFfa2", - "paUSD": "0x0000000000000000000000000000000000000000", "par": "0x78C48A7d7Fc69735fDab448fe6068bbA44a920E6", "weth": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1" }, @@ -30,8 +29,8 @@ "feeReceiver": "dao", "startPenaltyPercentage": "1000000000000000000", "timeLockDuration": 86400000, - "balancerV3Vault": "0x0000000000000000000000000000000000000000", - "auraVault": "0x0000000000000000000000000000000000000000", + "balancerV3Router": "0x0000000000000000000000000000000000000000", + "auraRewardsPool": "0x0000000000000000000000000000000000000000", "auraBoosterLite": "0x0000000000000000000000000000000000000000", "auraBPT": "0x0000000000000000000000000000000000000000", "balancerBPT": "0x0000000000000000000000000000000000000000" diff --git a/deploy/config/sepolia/config.json b/deploy/config/sepolia/config.json index 508f4d0..8109848 100644 --- a/deploy/config/sepolia/config.json +++ b/deploy/config/sepolia/config.json @@ -6,7 +6,6 @@ }, "tokens": { "prl": "0xfaD382eE9B8229fb9B05DF9F9391baC5DD81f346", - "paUSD": "0x0000000000000000000000000000000000000000", "par": "0x68E88c802F146eAD2f99F3A91Fb880D1A2509672", "weth": "0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9" }, @@ -30,9 +29,8 @@ "feeReceiver": "dao", "startPenaltyPercentage": "1000000000000000000", "timeLockDuration": 2419200, - "balancerV3Vault": "0x0000000000000000000000000000000000000000", - "auraVault": "0x0000000000000000000000000000000000000000", - "auraVaultRewardToken": "0x0000000000000000000000000000000000000000", + "balancerV3Router": "0x0000000000000000000000000000000000000000", + "auraRewardsPool": "0x0000000000000000000000000000000000000000", "auraBoosterLite": "0x0000000000000000000000000000000000000000", "auraBPT": "0x0000000000000000000000000000000000000000", "balancerBPT": "0x0000000000000000000000000000000000000000" diff --git a/deploy/scripts/fees/MainFeeDistributor.ts b/deploy/scripts/fees/MainFeeDistributor.ts index cc0cf3e..c6fea49 100644 --- a/deploy/scripts/fees/MainFeeDistributor.ts +++ b/deploy/scripts/fees/MainFeeDistributor.ts @@ -1,9 +1,8 @@ import assert from "assert"; -import { ethers } from "ethers"; import { type DeployFunction } from "hardhat-deploy/types"; -import { checkAddressValid, GAS, getTokenAddressFromConfig, isAddressValid } from "../../utils"; +import { checkAddressValid, getTokenAddressFromConfig } from "../../utils"; import { readFileSync } from "fs"; import { ConfigData } from "../../utils/types"; @@ -34,7 +33,6 @@ const deploy: DeployFunction = async (hre) => { args: [accessManager, bridgeableToken, feeToken], log: true, skipIfAlreadyDeployed: false, - ...GAS, }); console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${contract.address}`); diff --git a/deploy/scripts/fees/SideChainFeeCollector.ts b/deploy/scripts/fees/SideChainFeeCollector.ts index 8508d2e..71f842b 100644 --- a/deploy/scripts/fees/SideChainFeeCollector.ts +++ b/deploy/scripts/fees/SideChainFeeCollector.ts @@ -1,9 +1,8 @@ import assert from "assert"; -import { ethers } from "ethers"; import { type DeployFunction } from "hardhat-deploy/types"; -import { checkAddressValid, GAS, getLzEidReceiver, getTokenAddressFromConfig, isAddressValid } from "../../utils"; +import { checkAddressValid, getLzEidReceiver, getTokenAddressFromConfig } from "../../utils"; import { readFileSync } from "fs"; import { ConfigData } from "../../utils/types"; @@ -36,7 +35,6 @@ const deploy: DeployFunction = async (hre) => { args: [accessManager, lzEidReceiver, bridgeableToken, destinationReceiver, feeToken], log: true, skipIfAlreadyDeployed: false, - ...GAS, }); console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${contract.address}`); diff --git a/deploy/scripts/rewardMerkleDistributor/RewardMerkleDistributor.ts b/deploy/scripts/rewardMerkleDistributor/RewardMerkleDistributor.ts index 1faaaf7..79ac598 100644 --- a/deploy/scripts/rewardMerkleDistributor/RewardMerkleDistributor.ts +++ b/deploy/scripts/rewardMerkleDistributor/RewardMerkleDistributor.ts @@ -2,7 +2,7 @@ import assert from "assert"; import { type DeployFunction } from "hardhat-deploy/types"; -import { checkAddressValid, GAS, getTokenAddressFromConfig, getWalletAddressFromConfig } from "../../utils"; +import { checkAddressValid, getTokenAddressFromConfig, getWalletAddressFromConfig } from "../../utils"; import { readFileSync } from "fs"; import { ConfigData } from "../../utils/types"; @@ -37,7 +37,6 @@ const deploy: DeployFunction = async (hre) => { args: [accessManager, token, expiredRewardsRecipient], log: true, skipIfAlreadyDeployed: false, - ...GAS, }); console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${contract.address}`); diff --git a/deploy/scripts/sprl/sPRL1.ts b/deploy/scripts/sprl/sPRL1.ts index 12124c1..3b70243 100644 --- a/deploy/scripts/sprl/sPRL1.ts +++ b/deploy/scripts/sprl/sPRL1.ts @@ -1,9 +1,8 @@ import assert from "assert"; -import { ethers } from "ethers"; import { type DeployFunction } from "hardhat-deploy/types"; -import { GAS, getTokenAddressFromConfig, getWalletAddressFromConfig, isAddressValid } from "../../utils"; +import { getTokenAddressFromConfig, getWalletAddressFromConfig, isAddressValid } from "../../utils"; import { readFileSync } from "fs"; import { ConfigData } from "../../utils/types"; @@ -33,7 +32,6 @@ const deploy: DeployFunction = async (hre) => { args: [underlying, feeReceiver, accessManager, sprl1Data.startPenaltyPercentage, sprl1Data.timeLockDuration], log: true, skipIfAlreadyDeployed: false, - ...GAS, }); console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${contract.address}`); diff --git a/deploy/scripts/sprl/sPRL2.ts b/deploy/scripts/sprl/sPRL2.ts index 5c45610..0352088 100644 --- a/deploy/scripts/sprl/sPRL2.ts +++ b/deploy/scripts/sprl/sPRL2.ts @@ -1,15 +1,8 @@ import assert from "assert"; -import { ethers } from "ethers"; import { type DeployFunction } from "hardhat-deploy/types"; -import { - checkAddressValid, - GAS, - getTokenAddressFromConfig, - getWalletAddressFromConfig, - isAddressValid, -} from "../../utils"; +import { checkAddressValid, getTokenAddressFromConfig, getWalletAddressFromConfig, isAddressValid } from "../../utils"; import { readFileSync } from "fs"; import { ConfigData } from "../../utils/types"; @@ -34,13 +27,25 @@ const deploy: DeployFunction = async (hre) => { const prlToken = getTokenAddressFromConfig("prl", config); const wethToken = getTokenAddressFromConfig("weth", config); - const auraBPT = checkAddressValid(sprl2Data.auraBPT, "Aura BPT"); - const auraBoosterLite = checkAddressValid(sprl2Data.auraBoosterLite, "Aura Booster Lite"); - const auraVault = checkAddressValid(sprl2Data.auraVault, "Aura Vault"); - const balancerBPT = checkAddressValid(sprl2Data.balancerBPT, "Balancer BPT"); - + const permit2 = checkAddressValid(sprl2Data.permit2, "Permit2"); const feeReceiver = getWalletAddressFromConfig(sprl2Data.feeReceiver, config); + const balancerRouter = checkAddressValid(sprl2Data.balancerV3Router, "Balancer V3 Router"); + const balancerBPT = checkAddressValid(sprl2Data.balancerBPT, "Balancer BPT"); + const auraBoosterLite = checkAddressValid(sprl2Data.auraBoosterLite, "Aura Booster Lite"); + const auraRewardsPool = checkAddressValid(sprl2Data.auraRewardsPool, "Aura Rewards Pool"); + const auraBPT = checkAddressValid(sprl2Data.auraBPT, "Aura BPT"); + const rewardsTokens = sprl2Data.rewardsTokens.map((token) => checkAddressValid(token, "Reward Token")); + const BPTConfigParams = { + balancerRouter: balancerRouter, + auraBoosterLite: auraBoosterLite, + auraRewardsPool: auraRewardsPool, + balancerBPT: balancerBPT, + prl: prlToken, + weth: wethToken, + rewardTokens: rewardsTokens, + permit2: permit2, + }; const contract = await deploy(contractName, { from: deployer, args: [ @@ -49,15 +54,10 @@ const deploy: DeployFunction = async (hre) => { accessManager, sprl2Data.startPenaltyPercentage, sprl2Data.timeLockDuration, - balancerBPT, - auraBoosterLite, - auraVault, - prlToken, - wethToken, + BPTConfigParams, ], log: true, skipIfAlreadyDeployed: false, - ...GAS, }); console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${contract.address}`); diff --git a/deploy/utils/index.ts b/deploy/utils/index.ts index d6a0ef3..3e01454 100644 --- a/deploy/utils/index.ts +++ b/deploy/utils/index.ts @@ -1,13 +1,7 @@ -import type { CallOptions } from "hardhat-deploy/types"; import { ethers } from "ethers"; import { Address, ConfigData } from "./types"; import { EndpointId } from "@layerzerolabs/lz-definitions"; -export const GAS: CallOptions = { - maxFeePerGas: "20000000000", // 20 gwei - maxPriorityFeePerGas: "1000000000", -}; - export const getLzEidReceiver = (mainchain: string) => { if (mainchain === "sepolia") return EndpointId.SEPOLIA_V2_TESTNET; if (mainchain === "arbiSepolia") return EndpointId.ARBSEP_V2_TESTNET; diff --git a/deploy/utils/types.ts b/deploy/utils/types.ts index 8972662..bcfc308 100644 --- a/deploy/utils/types.ts +++ b/deploy/utils/types.ts @@ -10,7 +10,6 @@ export type ConfigData = { }; tokens: { prl: Address; - paUSD: Address; par: Address; weth: Address; }; @@ -31,13 +30,15 @@ export type ConfigData = { timeLockDuration: number; }; sprl2: { + permit2: Address; feeReceiver: string; startPenaltyPercentage: BigNumberish; timeLockDuration: number; - balancerV3Vault: Address; - auraVault: Address; + balancerV3Router: Address; + auraRewardsPool: Address; auraBoosterLite: Address; auraBPT: Address; balancerBPT: Address; + rewardsTokens: Address[]; }; }; diff --git a/package.json b/package.json index d153e59..8a0776a 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ }, "dependencies": { "@layerzerolabs/lz-evm-oapp-v2": "^3.0.14", - "@openzeppelin/contracts": "^5.1.0" + "@openzeppelin/contracts": "^5.1.0", + "ts-node": "^10.9.2" }, "devDependencies": { "@commitlint/cli": "^19.5.0", From af1e3c06b56617b433e2ea0f86dfc241cf63dd28 Mon Sep 17 00:00:00 2001 From: FabienC Date: Thu, 16 Apr 2026 14:30:34 +0300 Subject: [PATCH 4/4] feat: add mainnet deployment configs and role-setting scripts Add deployment configurations for mainnet, polygon, base, and sonic chains. Add Foundry scripts for setting access manager roles on deployed contracts. Update AURA_POOL_PID to 258 and add base/sonic network support. --- .prettierignore | 1 + contracts/sPRL/sPRL1.sol | 13 ++---- contracts/sPRL/sPRL2.sol | 10 +---- .../config/{ => base}/arbiSepolia/config.json | 2 +- deploy/config/base/config.json | 40 +++++++++++++++++++ deploy/config/mainnet/config.json | 40 +++++++++++++++++++ deploy/config/polygon/config.json | 40 +++++++++++++++++++ deploy/config/sepolia/config.json | 4 +- deploy/config/sonic/config.json | 40 +++++++++++++++++++ foundry.toml | 1 + hardhat.config.ts | 10 +++++ scripts/Base.s.sol | 38 ++++++++++++++++++ scripts/SetMainFeeDistributorRole.s.sol | 24 +++++++++++ scripts/SetRewardMerkleDistributor.s.sol | 26 ++++++++++++ scripts/SetSPRL1Role.s.sol | 23 +++++++++++ scripts/SetSPRL2Role.s.sol | 27 +++++++++++++ scripts/SetSideChainFeeCollectorRole.s.sol | 28 +++++++++++++ test/Base.t.sol | 6 +-- .../rewardMerkleDistributor/claim.t.sol | 31 ++++---------- .../forwardExpiredRewards.t.sol | 9 +---- test/mocks/TimeLockPenaltyERC20Mock.sol | 8 +--- utils/getRpcURL.ts | 6 +++ utils/getVerifyConfig.ts | 18 +++++++++ 23 files changed, 382 insertions(+), 63 deletions(-) rename deploy/config/{ => base}/arbiSepolia/config.json (95%) create mode 100644 deploy/config/base/config.json create mode 100644 deploy/config/mainnet/config.json create mode 100644 deploy/config/polygon/config.json create mode 100644 deploy/config/sonic/config.json create mode 100644 scripts/Base.s.sol create mode 100644 scripts/SetMainFeeDistributorRole.s.sol create mode 100644 scripts/SetRewardMerkleDistributor.s.sol create mode 100644 scripts/SetSPRL1Role.s.sol create mode 100644 scripts/SetSPRL2Role.s.sol create mode 100644 scripts/SetSideChainFeeCollectorRole.s.sol diff --git a/.prettierignore b/.prettierignore index d85a8b5..daf5db6 100644 --- a/.prettierignore +++ b/.prettierignore @@ -17,3 +17,4 @@ package-lock.json pnpm-lock.yaml yarn.lock deployments +.claude diff --git a/contracts/sPRL/sPRL1.sol b/contracts/sPRL/sPRL1.sol index 6838e79..b315ca2 100644 --- a/contracts/sPRL/sPRL1.sol +++ b/contracts/sPRL/sPRL1.sol @@ -32,13 +32,7 @@ contract sPRL1 is TimeLockPenaltyERC20 { uint64 _timeLockDuration ) TimeLockPenaltyERC20( - NAME, - SYMBOL, - _underlying, - _feeReceiver, - _accessManager, - _startPenaltyPercentage, - _timeLockDuration + NAME, SYMBOL, _underlying, _feeReceiver, _accessManager, _startPenaltyPercentage, _timeLockDuration ) { } @@ -71,8 +65,9 @@ contract sPRL1 is TimeLockPenaltyERC20 { nonReentrant { // @dev using try catch to avoid reverting the transaction in case of front-running - try IERC20Permit(address(underlying)).permit(msg.sender, address(this), _assetAmount, _deadline, _v, _r, _s) { - } catch { } + try IERC20Permit(address(underlying)) + .permit(msg.sender, address(this), _assetAmount, _deadline, _v, _r, _s) { } + catch { } underlying.safeTransferFrom(msg.sender, address(this), _assetAmount); _deposit(_assetAmount); } diff --git a/contracts/sPRL/sPRL2.sol b/contracts/sPRL/sPRL2.sol index b40f285..dcb19d5 100644 --- a/contracts/sPRL/sPRL2.sol +++ b/contracts/sPRL/sPRL2.sol @@ -24,7 +24,7 @@ contract sPRL2 is TimeLockPenaltyERC20 { string constant SYMBOL = "sPRL2"; /// @dev Aura Pool PID is hardcoded and must be updated before deploying - uint256 public constant AURA_POOL_PID = 244; + uint256 public constant AURA_POOL_PID = 258; //------------------------------------------- // Storage @@ -117,13 +117,7 @@ contract sPRL2 is TimeLockPenaltyERC20 { BPTConfigParams memory _configParams ) TimeLockPenaltyERC20( - NAME, - SYMBOL, - _stakedAuraBPT, - _feeReceiver, - _accessManager, - _startPenaltyPercentage, - _timeLockDuration + NAME, SYMBOL, _stakedAuraBPT, _feeReceiver, _accessManager, _startPenaltyPercentage, _timeLockDuration ) { if (_configParams.rewardTokens.length == 0) { diff --git a/deploy/config/arbiSepolia/config.json b/deploy/config/base/arbiSepolia/config.json similarity index 95% rename from deploy/config/arbiSepolia/config.json rename to deploy/config/base/arbiSepolia/config.json index fa1716c..4552ebc 100644 --- a/deploy/config/arbiSepolia/config.json +++ b/deploy/config/base/arbiSepolia/config.json @@ -2,7 +2,7 @@ "isMainChainFeeDistributor": false, "accessManager": "0xE2A0FA5A1e7315e6b89b12Ace2541A6a0d3E5370", "wallets": { - "dao": "0x3676b6ed4ae0c9ce3E0034510719fdF5fd585d55" + "dao": "0x66CcEC236bbcE5f1bBd1b2fC0a4014e57A55ad02" }, "tokens": { "prl": "0x0F4DE51EF1E7611aD0A9181F2d62B9c8408EFfa2", diff --git a/deploy/config/base/config.json b/deploy/config/base/config.json new file mode 100644 index 0000000..1f78628 --- /dev/null +++ b/deploy/config/base/config.json @@ -0,0 +1,40 @@ +{ + "isMainChainFeeDistributor": false, + "accessManager": "0x0e4e7Ca9D7b1e6293D0713EFEfB4BCA010DeBF46", + "wallets": { + "dao": "0xC5201FFE258a95Af986E7cD1fcaD54f3f63f2C95" + }, + "tokens": { + "prl": "0xfD28f108e95f4D41daAE9dbfFf707D677985998E", + "par": "0x0000000000000000000000000000000000000000", + "weth": "0x0000000000000000000000000000000000000000" + }, + "rewardMerkleDistributor": { + "token": "par", + "expiredRewardsRecipient": "dao" + }, + "feeDistributor": { + "mainChain": "polygon", + "destinationReceiver": "0x0000000000000000000000000000000000000000", + "feeToken": "par", + "bridgeableToken": "0x0000000000000000000000000000000000000000" + }, + "sprl1": { + "underlying": "prl", + "feeReceiver": "dao", + "startPenaltyPercentage": "500000000000000000", + "timeLockDuration": 2419200 + }, + "sprl2": { + "feeReceiver": "dao", + "permit2": "0x0000000000000000000000000000000000000000", + "startPenaltyPercentage": "500000000000000000", + "timeLockDuration": 2419200, + "balancerV3Router": "0x0000000000000000000000000000000000000000", + "auraRewardsPool": "0x0000000000000000000000000000000000000000", + "auraBoosterLite": "0x0000000000000000000000000000000000000000", + "auraBPT": "0x0000000000000000000000000000000000000000", + "balancerBPT": "0x0000000000000000000000000000000000000000", + "rewardsTokens": [] + } +} diff --git a/deploy/config/mainnet/config.json b/deploy/config/mainnet/config.json new file mode 100644 index 0000000..c94ef9b --- /dev/null +++ b/deploy/config/mainnet/config.json @@ -0,0 +1,40 @@ +{ + "isMainChainFeeDistributor": false, + "accessManager": "0x94Ea8800444017695345156319e96bdB1E355F7a", + "wallets": { + "dao": "0x25Fc7ffa8f9da3582a36633d04804F0004706F9b" + }, + "tokens": { + "prl": "0x6c0aeceeDc55c9d55d8B99216a670D85330941c3", + "par": "0x68037790a0229e9ce6eaa8a99ea92964106c4703", + "weth": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" + }, + "rewardMerkleDistributor": { + "token": "par", + "expiredRewardsRecipient": "dao" + }, + "feeDistributor": { + "mainChain": "polygon", + "destinationReceiver": "0x90337e484B1Cb02132fc150d3Afa262147348545", + "feeToken": "par", + "bridgeableToken": "0x74e3f9D724Da6D7e4db8EcAb4f18e6ba44f60e30" + }, + "sprl1": { + "underlying": "prl", + "feeReceiver": "dao", + "startPenaltyPercentage": "500000000000000000", + "timeLockDuration": 2419200 + }, + "sprl2": { + "feeReceiver": "dao", + "permit2": "0x000000000022D473030F116dDEE9F6B43aC78BA3", + "startPenaltyPercentage": "500000000000000000", + "timeLockDuration": 60, + "balancerV3Router": "0x5C6fb490BDFD3246EB0bB062c168DeCAF4bD9FDd", + "auraRewardsPool": "0x486Be73794Ec19f3e9cF57f06f03fDCf7F0A9da4", + "auraBoosterLite": "0xA57b8d98dAE62B26Ec3bcC4a365338157060B234", + "auraBPT": "0x486Be73794Ec19f3e9cF57f06f03fDCf7F0A9da4", + "balancerBPT": "0x1846C6cBE0D433e152fA358e5fF27968E18bcE7c", + "rewardsTokens": ["0xba100000625a3754423978a60c9317c58a424e3d", "0xC0c293ce456fF0ED870ADd98a0828Dd4d2903DBF"] + } +} diff --git a/deploy/config/polygon/config.json b/deploy/config/polygon/config.json new file mode 100644 index 0000000..456dcc8 --- /dev/null +++ b/deploy/config/polygon/config.json @@ -0,0 +1,40 @@ +{ + "isMainChainFeeDistributor": true, + "accessManager": "0x7Df74BBB6F82eC1BCB1562a30ef5Bf5c326e2811", + "wallets": { + "dao": "0x2046c0416A558C40cb112E5ebB0Ca764c3C5c32a" + }, + "tokens": { + "prl": "0x7790dd69aa10eD3f1271E41CD7222D2a7d2D5948", + "par": "0xE2Aa7db6dA1dAE97C5f5C6914d285fBfCC32A128", + "weth": "0x0000000000000000000000000000000000000000" + }, + "rewardMerkleDistributor": { + "token": "par", + "expiredRewardsRecipient": "dao" + }, + "feeDistributor": { + "mainChain": "polygon", + "destinationReceiver": "0x0000000000000000000000000000000000000000", + "feeToken": "par", + "bridgeableToken": "0xE462Df8d4Aa7Db3aeCfe810ec8D1fa4f716BC9a8" + }, + "sprl1": { + "underlying": "prl", + "feeReceiver": "dao", + "startPenaltyPercentage": "500000000000000000", + "timeLockDuration": 2419200 + }, + "sprl2": { + "feeReceiver": "dao", + "permit2": "0x0000000000000000000000000000000000000000", + "startPenaltyPercentage": "500000000000000000", + "timeLockDuration": 2419200, + "balancerV3Router": "0x0000000000000000000000000000000000000000", + "auraRewardsPool": "0x0000000000000000000000000000000000000000", + "auraBoosterLite": "0x0000000000000000000000000000000000000000", + "auraBPT": "0x0000000000000000000000000000000000000000", + "balancerBPT": "0x0000000000000000000000000000000000000000", + "rewardsTokens": [] + } +} diff --git a/deploy/config/sepolia/config.json b/deploy/config/sepolia/config.json index 8109848..7a3c1cd 100644 --- a/deploy/config/sepolia/config.json +++ b/deploy/config/sepolia/config.json @@ -1,8 +1,8 @@ { "isMainChainFeeDistributor": true, - "accessManager": "0xe29F44Aa83EB42BA823719EA1D2d84861f72A5D0", + "accessManager": "0xfD28f108e95f4D41daAE9dbfFf707D677985998E", "wallets": { - "dao": "0x3676b6ed4ae0c9ce3E0034510719fdF5fd585d55" + "dao": "0x66CcEC236bbcE5f1bBd1b2fC0a4014e57A55ad02" }, "tokens": { "prl": "0xfaD382eE9B8229fb9B05DF9F9391baC5DD81f346", diff --git a/deploy/config/sonic/config.json b/deploy/config/sonic/config.json new file mode 100644 index 0000000..9b510d8 --- /dev/null +++ b/deploy/config/sonic/config.json @@ -0,0 +1,40 @@ +{ + "isMainChainFeeDistributor": false, + "accessManager": "0x8eFb3DED78FbaEF2a4eFe01E01BBD911E4094b78", + "wallets": { + "dao": "0xC5201FFE258a95Af986E7cD1fcaD54f3f63f2C95" + }, + "tokens": { + "prl": "0xfD28f108e95f4D41daAE9dbfFf707D677985998E", + "par": "0x0000000000000000000000000000000000000000", + "weth": "0x0000000000000000000000000000000000000000" + }, + "rewardMerkleDistributor": { + "token": "par", + "expiredRewardsRecipient": "dao" + }, + "feeDistributor": { + "mainChain": "polygon", + "destinationReceiver": "0x0000000000000000000000000000000000000000", + "feeToken": "par", + "bridgeableToken": "0x0000000000000000000000000000000000000000" + }, + "sprl1": { + "underlying": "prl", + "feeReceiver": "dao", + "startPenaltyPercentage": "500000000000000000", + "timeLockDuration": 2419200 + }, + "sprl2": { + "feeReceiver": "dao", + "permit2": "0x0000000000000000000000000000000000000000", + "startPenaltyPercentage": "500000000000000000", + "timeLockDuration": 2419200, + "balancerV3Router": "0x0000000000000000000000000000000000000000", + "auraRewardsPool": "0x0000000000000000000000000000000000000000", + "auraBoosterLite": "0x0000000000000000000000000000000000000000", + "auraBPT": "0x0000000000000000000000000000000000000000", + "balancerBPT": "0x0000000000000000000000000000000000000000", + "rewardsTokens": [] + } +} diff --git a/foundry.toml b/foundry.toml index 3319e43..c7a621d 100644 --- a/foundry.toml +++ b/foundry.toml @@ -35,3 +35,4 @@ [rpc_endpoints] mainnet = "https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}" +polygon = "https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}" \ No newline at end of file diff --git a/hardhat.config.ts b/hardhat.config.ts index f4719b8..bc4d64f 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -59,6 +59,16 @@ const config: HardhatUserConfig = { url: getRpcURL("polygon"), verify: getVerifyConfig("polygon"), }, + base: { + url: getRpcURL("base"), + verify: getVerifyConfig("base"), + accounts, + }, + sonic: { + url: getRpcURL("sonic"), + verify: getVerifyConfig("sonic"), + accounts, + }, }, namedAccounts: { deployer: { diff --git a/scripts/Base.s.sol b/scripts/Base.s.sol new file mode 100644 index 0000000..d507b0c --- /dev/null +++ b/scripts/Base.s.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import { Script, console2 } from "@forge-std/Script.sol"; + +import { IAccessManager } from "@openzeppelin/contracts/access/manager/IAccessManager.sol"; + +contract BaseScript is Script { + /// @dev The address of the transaction broadcaster. + address internal broadcaster; + + IAccessManager accessManager = IAccessManager(0x94Ea8800444017695345156319e96bdB1E355F7a); + + modifier broadcast() { + uint256 privateKey = vm.envUint("PRIVATE_KEY"); + vm.startBroadcast(privateKey); + broadcaster = vm.addr(privateKey); + _; + vm.stopBroadcast(); + } +} + +library Roles { + uint64 constant GOVERNOR_ROLE = 10; + uint64 constant GOVERNOR_ROLE_TIMELOCK = 11; + uint64 constant GUARDIAN_ROLE = 20; + uint64 constant GUARDIAN_ROLE_TIMELOCK = 21; + uint64 constant KEEPER_ROLE = 30; + uint64 constant KEEPER_ROLE_TIMELOCK = 31; + uint64 constant EURp_MINTER_ROLE = 100; + uint64 constant EURp_MINTER_ROLE_TIMELOCK = 105; + uint64 constant USDp_MINTER_ROLE = 110; + uint64 constant USDp_MINTER_ROLE_TIMELOCK = 115; + uint64 constant ETHp_MINTER_ROLE = 120; + uint64 constant ETHp_MINTER_ROLE_TIMELOCK = 125; + uint64 constant BTCp_MINTER_ROLE = 130; + uint64 constant BTCp_MINTER_ROLE_TIMELOCK = 135; +} diff --git a/scripts/SetMainFeeDistributorRole.s.sol b/scripts/SetMainFeeDistributorRole.s.sol new file mode 100644 index 0000000..4fbcd98 --- /dev/null +++ b/scripts/SetMainFeeDistributorRole.s.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import "./Base.s.sol"; + +import { MainFeeDistributor } from "contracts/fees/MainFeeDistributor.sol"; +import { FeeCollectorCore } from "contracts/fees/FeeCollectorCore.sol"; + +contract SetMainFeeDistributorRole is BaseScript { + address mainFeeDistributor = 0x90337e484B1Cb02132fc150d3Afa262147348545; + + function run() public broadcast { + bytes4[] memory guardianSelectors = new bytes4[](3); + guardianSelectors[0] = FeeCollectorCore.pause.selector; + guardianSelectors[1] = FeeCollectorCore.unpause.selector; + guardianSelectors[2] = FeeCollectorCore.emergencyRescue.selector; + accessManager.setTargetFunctionRole(mainFeeDistributor, guardianSelectors, Roles.GUARDIAN_ROLE); + + bytes4[] memory governorSelectors = new bytes4[](2); + governorSelectors[0] = MainFeeDistributor.updateBridgeableToken.selector; + governorSelectors[1] = MainFeeDistributor.updateFeeReceivers.selector; + accessManager.setTargetFunctionRole(mainFeeDistributor, governorSelectors, Roles.GOVERNOR_ROLE); + } +} diff --git a/scripts/SetRewardMerkleDistributor.s.sol b/scripts/SetRewardMerkleDistributor.s.sol new file mode 100644 index 0000000..96140df --- /dev/null +++ b/scripts/SetRewardMerkleDistributor.s.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import "./Base.s.sol"; + +import { RewardMerkleDistributor } from "contracts/rewardMerkleDistributor/RewardMerkleDistributor.sol"; + +contract SetRewardMerkleDistributorRole is BaseScript { + address rewardMerkleDistributor = 0x7b54f3D993d3bcA077946034Ea710F9c07420C72; + + function run() public broadcast { + bytes4[] memory guardianSelectors = new bytes4[](3); + guardianSelectors[0] = RewardMerkleDistributor.pause.selector; + guardianSelectors[1] = RewardMerkleDistributor.unpause.selector; + guardianSelectors[2] = RewardMerkleDistributor.emergencyRescue.selector; + accessManager.setTargetFunctionRole(rewardMerkleDistributor, guardianSelectors, Roles.GUARDIAN_ROLE); + + bytes4[] memory governorSelectors = new bytes4[](1); + governorSelectors[0] = RewardMerkleDistributor.updateExpiredRewardsRecipient.selector; + accessManager.setTargetFunctionRole(rewardMerkleDistributor, governorSelectors, Roles.GOVERNOR_ROLE); + + bytes4[] memory keeperSelectors = new bytes4[](1); + keeperSelectors[0] = RewardMerkleDistributor.updateMerkleDrop.selector; + accessManager.setTargetFunctionRole(rewardMerkleDistributor, keeperSelectors, Roles.KEEPER_ROLE); + } +} diff --git a/scripts/SetSPRL1Role.s.sol b/scripts/SetSPRL1Role.s.sol new file mode 100644 index 0000000..00043a1 --- /dev/null +++ b/scripts/SetSPRL1Role.s.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import "./Base.s.sol"; + +import { TimeLockPenaltyERC20 } from "contracts/sPRL/TimeLockPenaltyERC20.sol"; + +contract SetSPRL1Role is BaseScript { + address sprl1 = 0x7Df74BBB6F82eC1BCB1562a30ef5Bf5c326e2811; + + function run() public broadcast { + bytes4[] memory guardianSelectors = new bytes4[](2); + guardianSelectors[0] = TimeLockPenaltyERC20.pause.selector; + guardianSelectors[1] = TimeLockPenaltyERC20.unpause.selector; + accessManager.setTargetFunctionRole(sprl1, guardianSelectors, Roles.GUARDIAN_ROLE); + + bytes4[] memory governorSelectors = new bytes4[](3); + governorSelectors[0] = TimeLockPenaltyERC20.updateFeeReceiver.selector; + governorSelectors[1] = TimeLockPenaltyERC20.updateStartPenaltyPercentage.selector; + governorSelectors[2] = TimeLockPenaltyERC20.updateTimeLockDuration.selector; + accessManager.setTargetFunctionRole(sprl1, governorSelectors, Roles.GOVERNOR_ROLE); + } +} diff --git a/scripts/SetSPRL2Role.s.sol b/scripts/SetSPRL2Role.s.sol new file mode 100644 index 0000000..0a3d99a --- /dev/null +++ b/scripts/SetSPRL2Role.s.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import "./Base.s.sol"; + +import { sPRL2 } from "contracts/sPRL/sPRL2.sol"; +import { TimeLockPenaltyERC20 } from "contracts/sPRL/TimeLockPenaltyERC20.sol"; + +contract SetSPRL2Role is BaseScript { + address sprl2 = 0x90337e484B1Cb02132fc150d3Afa262147348545; + + function run() public broadcast { + bytes4[] memory guardianSelectors = new bytes4[](2); + guardianSelectors[0] = TimeLockPenaltyERC20.pause.selector; + guardianSelectors[1] = TimeLockPenaltyERC20.unpause.selector; + console2.log("guardianSelectors", guardianSelectors); + // accessManager.setTargetFunctionRole(sprl2, guardianSelectors, Roles.GUARDIAN_ROLE); + + bytes4[] memory governorSelectors = new bytes4[](4); + governorSelectors[0] = TimeLockPenaltyERC20.updateFeeReceiver.selector; + governorSelectors[1] = TimeLockPenaltyERC20.updateStartPenaltyPercentage.selector; + governorSelectors[2] = TimeLockPenaltyERC20.updateTimeLockDuration.selector; + governorSelectors[3] = sPRL2.updateRewardTokens.selector; + console2.log("governorSelectors", governorSelectors); + // accessManager.setTargetFunctionRole(sprl2, governorSelectors, Roles.GOVERNOR_ROLE); + } +} diff --git a/scripts/SetSideChainFeeCollectorRole.s.sol b/scripts/SetSideChainFeeCollectorRole.s.sol new file mode 100644 index 0000000..0595cc8 --- /dev/null +++ b/scripts/SetSideChainFeeCollectorRole.s.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import "./Base.s.sol"; + +import { SideChainFeeCollector } from "contracts/fees/SideChainFeeCollector.sol"; +import { FeeCollectorCore } from "contracts/fees/FeeCollectorCore.sol"; + +contract SetSideChainFeeCollectorRole is BaseScript { + address sideChainFeeCollector = 0x2A4ABC8dcBE2f68E48dFc0db5784C71dB8d5B89c; + + function run() public broadcast { + bytes4[] memory guardianSelectors = new bytes4[](3); + guardianSelectors[0] = FeeCollectorCore.pause.selector; + guardianSelectors[1] = FeeCollectorCore.unpause.selector; + guardianSelectors[2] = FeeCollectorCore.emergencyRescue.selector; + accessManager.setTargetFunctionRole(sideChainFeeCollector, guardianSelectors, Roles.GUARDIAN_ROLE); + + bytes4[] memory governorSelectors = new bytes4[](2); + governorSelectors[0] = SideChainFeeCollector.updateDestinationReceiver.selector; + governorSelectors[1] = SideChainFeeCollector.updateBridgeableToken.selector; + accessManager.setTargetFunctionRole(sideChainFeeCollector, governorSelectors, Roles.GOVERNOR_ROLE); + + bytes4[] memory keeperSelectors = new bytes4[](1); + keeperSelectors[0] = SideChainFeeCollector.swapLzToken.selector; + accessManager.setTargetFunctionRole(sideChainFeeCollector, keeperSelectors, Roles.KEEPER_ROLE); + } +} diff --git a/test/Base.t.sol b/test/Base.t.sol index a9e9592..901a176 100644 --- a/test/Base.t.sol +++ b/test/Base.t.sol @@ -78,11 +78,7 @@ abstract contract Base_Test is Test, Deploys, Assertions, Defaults, Utils { address owner = vm.addr(privateKey); deadline = block.timestamp + 1 days; SigUtils.Permit memory permit = SigUtils.Permit({ - owner: owner, - spender: spender, - value: amount, - nonce: IERC20Permit(token).nonces(owner), - deadline: deadline + owner: owner, spender: spender, value: amount, nonce: IERC20Permit(token).nonces(owner), deadline: deadline }); bytes32 digest = sigUtils.getTypedDataHash(permit); diff --git a/test/integrations/rewardMerkleDistributor/claim.t.sol b/test/integrations/rewardMerkleDistributor/claim.t.sol index c54a03f..d3557b4 100644 --- a/test/integrations/rewardMerkleDistributor/claim.t.sol +++ b/test/integrations/rewardMerkleDistributor/claim.t.sol @@ -51,6 +51,7 @@ contract RewardMerkleDistributor_Claim_Integrations_Test is Integrations_Test { startTime: uint64(block.timestamp) + firstEpochStartDelay, expiryTime: uint64(block.timestamp) + firstEpochStartDelay + epochLength * 6 }); + rewardMerkleDistributor.updateMerkleDrop(firstEpochId, firstEpochMerkleDrop); /// @dev Leaves are added in the order of the merkle tree's secondEpochLeaves. @@ -94,10 +95,7 @@ contract RewardMerkleDistributor_Claim_Integrations_Test is Integrations_Test { RewardMerkleDistributor.ClaimCallData[] memory claimsData = new RewardMerkleDistributor.ClaimCallData[](1); claimsData[0] = RewardMerkleDistributor.ClaimCallData({ - epochId: firstEpochId, - account: users.alice.addr, - amount: firstClaimRewardsAmount, - merkleProof: proof + epochId: firstEpochId, account: users.alice.addr, amount: firstClaimRewardsAmount, merkleProof: proof }); rewardMerkleDistributor.claims(claimsData); @@ -147,10 +145,7 @@ contract RewardMerkleDistributor_Claim_Integrations_Test is Integrations_Test { RewardMerkleDistributor.ClaimCallData[] memory claimsData = new RewardMerkleDistributor.ClaimCallData[](1); claimsData[0] = RewardMerkleDistributor.ClaimCallData({ - epochId: firstEpochId, - account: users.alice.addr, - amount: firstClaimRewardsAmount, - merkleProof: proof + epochId: firstEpochId, account: users.alice.addr, amount: firstClaimRewardsAmount, merkleProof: proof }); vm.warp(firstEpochMerkleDrop.expiryTime + 1); vm.expectRevert(RewardMerkleDistributor.EpochExpired.selector); @@ -163,10 +158,7 @@ contract RewardMerkleDistributor_Claim_Integrations_Test is Integrations_Test { RewardMerkleDistributor.ClaimCallData[] memory claimsData = new RewardMerkleDistributor.ClaimCallData[](1); claimsData[0] = RewardMerkleDistributor.ClaimCallData({ - epochId: secondEpochId, - account: users.alice.addr, - amount: secondClaimRewardsAmount, - merkleProof: proof + epochId: secondEpochId, account: users.alice.addr, amount: secondClaimRewardsAmount, merkleProof: proof }); vm.expectRevert(RewardMerkleDistributor.NotStarted.selector); rewardMerkleDistributor.claims(claimsData); @@ -179,10 +171,7 @@ contract RewardMerkleDistributor_Claim_Integrations_Test is Integrations_Test { RewardMerkleDistributor.ClaimCallData[] memory claimsData = new RewardMerkleDistributor.ClaimCallData[](1); claimsData[0] = RewardMerkleDistributor.ClaimCallData({ - epochId: firstEpochId, - account: users.alice.addr, - amount: firstClaimRewardsAmount, - merkleProof: proof + epochId: firstEpochId, account: users.alice.addr, amount: firstClaimRewardsAmount, merkleProof: proof }); rewardMerkleDistributor.claims(claimsData); @@ -198,10 +187,7 @@ contract RewardMerkleDistributor_Claim_Integrations_Test is Integrations_Test { RewardMerkleDistributor.ClaimCallData[] memory claimsData = new RewardMerkleDistributor.ClaimCallData[](1); claimsData[0] = RewardMerkleDistributor.ClaimCallData({ - epochId: firstEpochId, - account: users.alice.addr, - amount: firstClaimRewardsAmount * 100, - merkleProof: proof + epochId: firstEpochId, account: users.alice.addr, amount: firstClaimRewardsAmount * 100, merkleProof: proof }); vm.expectRevert(RewardMerkleDistributor.ProofInvalid.selector); @@ -232,10 +218,7 @@ contract RewardMerkleDistributor_Claim_Integrations_Test is Integrations_Test { RewardMerkleDistributor.ClaimCallData[] memory claimsData = new RewardMerkleDistributor.ClaimCallData[](1); claimsData[0] = RewardMerkleDistributor.ClaimCallData({ - epochId: firstEpochId, - account: users.alice.addr, - amount: firstClaimRewardsAmount, - merkleProof: proof + epochId: firstEpochId, account: users.alice.addr, amount: firstClaimRewardsAmount, merkleProof: proof }); vm.expectRevert(RewardMerkleDistributor.TotalEpochRewardsExceeded.selector); diff --git a/test/integrations/rewardMerkleDistributor/forwardExpiredRewards.t.sol b/test/integrations/rewardMerkleDistributor/forwardExpiredRewards.t.sol index 085212c..06ccb6b 100644 --- a/test/integrations/rewardMerkleDistributor/forwardExpiredRewards.t.sol +++ b/test/integrations/rewardMerkleDistributor/forwardExpiredRewards.t.sol @@ -120,10 +120,7 @@ contract RewardMerkleDistributor_ForwardExpiredRewards_Integrations_Test is Inte RewardMerkleDistributor.ClaimCallData[] memory claimsData = new RewardMerkleDistributor.ClaimCallData[](1); claimsData[0] = RewardMerkleDistributor.ClaimCallData({ - epochId: firstEpochId, - account: users.alice.addr, - amount: firstRewardsAmount, - merkleProof: proof + epochId: firstEpochId, account: users.alice.addr, amount: firstRewardsAmount, merkleProof: proof }); rewardMerkleDistributor.claims(claimsData); @@ -163,9 +160,7 @@ contract RewardMerkleDistributor_ForwardExpiredRewards_Integrations_Test is Inte rewardMerkleDistributor.forwardExpiredRewards(epochIds); } - function test_RewardMerkleDistributor_ForwardExpiredRewards_RevertWhen_EpochIsNotExpired_SeveralEpochs() - external - { + function test_RewardMerkleDistributor_ForwardExpiredRewards_RevertWhen_EpochIsNotExpired_SeveralEpochs() external { vm.startPrank(users.admin.addr); uint64[] memory epochIds = new uint64[](2); epochIds[0] = firstEpochId; diff --git a/test/mocks/TimeLockPenaltyERC20Mock.sol b/test/mocks/TimeLockPenaltyERC20Mock.sol index e8db9fa..7e47417 100644 --- a/test/mocks/TimeLockPenaltyERC20Mock.sol +++ b/test/mocks/TimeLockPenaltyERC20Mock.sol @@ -14,13 +14,7 @@ contract TimeLockPenaltyERC20Mock is TimeLockPenaltyERC20 { uint64 timeLockDuration ) TimeLockPenaltyERC20( - name, - symbol, - underlying, - feeReceiver, - accessManager, - startPenaltyPercentage, - timeLockDuration + name, symbol, underlying, feeReceiver, accessManager, startPenaltyPercentage, timeLockDuration ) { } } diff --git a/utils/getRpcURL.ts b/utils/getRpcURL.ts index aa2f387..2a77467 100644 --- a/utils/getRpcURL.ts +++ b/utils/getRpcURL.ts @@ -20,6 +20,12 @@ export const getRpcURL = (network: string): string => { case "fantom": { return `https://fantom-mainnet.g.alchemy.com/v2/${apiKey}`; } + case "base": { + return `https://base-mainnet.g.alchemy.com/v2/${apiKey}`; + } + case "sonic": { + return `https://sonic-mainnet.g.alchemy.com/v2/${apiKey}`; + } default: { throw new Error(`${network} Network RPC not configured`); } diff --git a/utils/getVerifyConfig.ts b/utils/getVerifyConfig.ts index 5541052..558c7f4 100644 --- a/utils/getVerifyConfig.ts +++ b/utils/getVerifyConfig.ts @@ -61,6 +61,24 @@ export const getVerifyConfig = (network: string): VerifyConfig => { }, }; } + case "base": { + if (!process.env.BASE_ETHERSCAN_API_KEY) throw new Error("BASE_ETHERSCAN_API_KEY is not set"); + return { + etherscan: { + apiUrl: "https://api.basescan.org", + apiKey: process.env.BASE_ETHERSCAN_API_KEY, + }, + }; + } + case "sonic": { + if (!process.env.SONIC_ETHERSCAN_API_KEY) throw new Error("SONIC_ETHERSCAN_API_KEY is not set"); + return { + etherscan: { + apiUrl: "https://api.sonicscan.org", + apiKey: process.env.SONIC_ETHERSCAN_API_KEY, + }, + }; + } default: { throw new Error(`${network} Network Verify not configured`); }