-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: foundry support for missing test and deployment script #45
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Deployer private key | ||
PRIVATE_KEY= | ||
|
||
# RPCs | ||
ARBITRUM_RPC_URL= | ||
BASE_RPC_URL= | ||
ETHEREUM_RPC_URL= | ||
FRAXTAL_RPC_URL= | ||
GNOSIS_RPC_URL= | ||
OPTIMISM_RPC_URL= | ||
POLYGON_RPC_URL= | ||
|
||
# Etherscan APIs | ||
ETHERSCAN_ARBITRUM_API_KEY= | ||
ETHERSCAN_BASE_API_KEY= | ||
ETHERSCAN_ETHEREUM_API_KEY= | ||
ETHERSCAN_FRAXTAL_API_KEY= | ||
ETHERSCAN_GNOSIS_API_KEY= | ||
ETHERSCAN_OPTIMISM_API_KEY= | ||
ETHERSCAN_POLYGON_API_KEY= |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "lib/forge-std"] | ||
path = lib/forge-std | ||
url = https://github.com/foundry-rs/forge-std.git |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
-include .env | ||
|
||
# command: test the whole script without broadcasting the transaction into the chain to spot early errors | ||
deployPolygonDry: | ||
forge script foundry_scripts/InjectorInfraDeployment.s.sol \ | ||
--rpc-url polygon \ | ||
--slow \ | ||
-vvvv | ||
|
||
deployPolygonBroadcastAndVerify: | ||
forge script foundry_scripts/InjectorInfraDeployment.s.sol \ | ||
--rpc-url polygon \ | ||
--slow \ | ||
--broadcast \ | ||
--verify \ | ||
-vvvv | ||
|
||
deployMultiChainDry: | ||
forge script foundry_scripts/InjectorInfraMultiChainDeployment.s.sol \ | ||
--rpc-url polygon \ | ||
--slow \ | ||
-- multi \ | ||
-vvvv | ||
|
||
deployMultiChainBroadcastAndVerify: | ||
forge script foundry_scripts/InjectorInfraMultiChainDeployment.s.sol \ | ||
--rpc-url polygon \ | ||
--slow \ | ||
-- multi \ | ||
--broadcast \ | ||
--verify \ | ||
-vvvv | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[profile.default] | ||
src = 'contracts' | ||
out = "out" | ||
libs = ['node_modules','lib'] | ||
test = 'foundry_test' | ||
solc = '0.8.25' | ||
|
||
[fmt] | ||
ignore = ['./contracts/**/*'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @note here i'm opting to avoid linting the contracts all together. it can be something to consider tho once all issues/prs are close |
||
|
||
[rpc_endpoints] | ||
arbitrum = "${ARBITRUM_RPC_URL}" | ||
base = "${BASE_RPC_URL}" | ||
ethereum = "${ETHEREUM_RPC_URL}" | ||
fraxtal = "${FRAXTAL_RPC_URL}" | ||
gnosis = "${GNOSIS_RPC_URL}" | ||
optimism = "${OPTIMISM_RPC_URL}" | ||
polygon = "${POLYGON_RPC_URL}" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
pragma solidity ^0.8.25; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
|
||
import {ChildChainGaugeInjectorV2} from "../contracts/ChildChainGaugeInjectorV2.sol"; | ||
import {ChildChainGaugeInjectorV2Factory} from "../contracts/injectorFactoryV2.sol"; | ||
|
||
/// @notice Deploys the v2 infrastructure for the injectors in the following order: | ||
/// 1. {ChildChainGaugeInjectorV2} -> singleton/implementation purposes (helps verifying in etherscan etc) | ||
/// 2. {ChildChainGaugeInjectorV2Factory} | ||
contract InjectorInfraDeployment is Script { | ||
// injector infrastructure | ||
ChildChainGaugeInjectorV2 injectorImpl; | ||
ChildChainGaugeInjectorV2Factory injectorFactory; | ||
|
||
function run() public { | ||
// read pk from `.env` | ||
uint256 pk = vm.envUint("PRIVATE_KEY"); | ||
vm.startBroadcast(pk); | ||
|
||
// 1. {ChildChainGaugeInjectorV2} | ||
injectorImpl = new ChildChainGaugeInjectorV2(); | ||
|
||
// 2. {ChildChainGaugeInjectorV2Factory} | ||
injectorFactory = new ChildChainGaugeInjectorV2Factory(address(injectorImpl)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
pragma solidity ^0.8.25; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
|
||
import {ChildChainGaugeInjectorV2} from "../contracts/ChildChainGaugeInjectorV2.sol"; | ||
import {ChildChainGaugeInjectorV2Factory} from "../contracts/injectorFactoryV2.sol"; | ||
|
||
/// @notice Deploys the v2 infrastructure for the injectors in all chains in `foundry.toml` in the following order: | ||
/// 1. {ChildChainGaugeInjectorV2} -> singleton/implementation purposes (helps verifying in etherscan etc) | ||
/// 2. {ChildChainGaugeInjectorV2Factory} | ||
contract InjectorInfraMultiChainDeployment is Script { | ||
enum Chains { | ||
ARBITRUM, | ||
BASE, | ||
ETHEREUM, | ||
FRAXTAL, | ||
GNOSIS, | ||
OPTIMISM, | ||
POLYGON | ||
} | ||
|
||
// injector infrastructure | ||
ChildChainGaugeInjectorV2 injectorImpl; | ||
ChildChainGaugeInjectorV2Factory injectorFactory; | ||
|
||
mapping(Chains chain => string rpcAlias) public availableChains; | ||
|
||
constructor() { | ||
availableChains[Chains.ARBITRUM] = "arbitrum"; | ||
availableChains[Chains.BASE] = "base"; | ||
availableChains[Chains.ETHEREUM] = "ethereum"; | ||
availableChains[Chains.FRAXTAL] = "fraxtal"; | ||
availableChains[Chains.GNOSIS] = "gnosis"; | ||
availableChains[Chains.OPTIMISM] = "optimism"; | ||
availableChains[Chains.POLYGON] = "polygon"; | ||
} | ||
|
||
/// @dev broadcast transaction modifier | ||
/// @param pk private key to broadcast transaction | ||
modifier broadcast(uint256 pk) { | ||
vm.startBroadcast(pk); | ||
|
||
_; | ||
|
||
vm.stopBroadcast(); | ||
} | ||
|
||
function run() public { | ||
// read pk from `.env` | ||
uint256 pk = vm.envUint("PRIVATE_KEY"); | ||
|
||
// @note the array can be updated depending on your target chains to deploy | ||
// @note by default the script will deploy in all chains available in the toml file | ||
Chains[] memory targetDeploymentChains = new Chains[](6); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here you can target the specifics chains which you will like to deploy at once, remove as you may see fit, but also remember to adapt the length of the array |
||
|
||
targetDeploymentChains[0] = Chains.ARBITRUM; | ||
targetDeploymentChains[1] = Chains.BASE; | ||
targetDeploymentChains[2] = Chains.ETHEREUM; | ||
targetDeploymentChains[3] = Chains.GNOSIS; | ||
targetDeploymentChains[4] = Chains.OPTIMISM; | ||
targetDeploymentChains[5] = Chains.POLYGON; | ||
// @note fraxtal rpc gives sometimes problems | ||
|
||
for (uint256 i = 0; i < targetDeploymentChains.length; i++) { | ||
_deploy(targetDeploymentChains[i], pk); | ||
} | ||
} | ||
|
||
/// @dev Helper to point into a specific chain | ||
/// @param _targetChain chain to deploy | ||
/// @param _pk private key to broadcast transaction | ||
function _deploy(Chains _targetChain, uint256 _pk) internal { | ||
vm.createSelectFork(availableChains[_targetChain]); | ||
|
||
_infraDeployment(_pk); | ||
} | ||
|
||
/// @dev Helper to deploy the factory and singleton | ||
/// @param _pk private key to broadcast transaction | ||
function _infraDeployment(uint256 _pk) internal broadcast(_pk) { | ||
// 1. {ChildChainGaugeInjectorV2} | ||
injectorImpl = new ChildChainGaugeInjectorV2(); | ||
|
||
// 2. {ChildChainGaugeInjectorV2Factory} | ||
injectorFactory = new ChildChainGaugeInjectorV2Factory(address(injectorImpl)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.25; | ||
|
||
import "forge-std/Test.sol"; | ||
|
||
import {IChildChainGauge} from "../contracts/interfaces/balancer/IChildChainGauge.sol"; | ||
|
||
import {ChildChainGaugeInjectorV2} from "../contracts/ChildChainGaugeInjectorV2.sol"; | ||
import {ChildChainGaugeInjectorV2Factory} from "../contracts/injectorFactoryV2.sol"; | ||
|
||
contract BaseFixture is Test { | ||
// injector instance | ||
ChildChainGaugeInjectorV2 injector; | ||
|
||
// factory instance | ||
ChildChainGaugeInjectorV2Factory factory; | ||
|
||
// constants | ||
address constant GAUGE = 0x3Eae4a1c2E36870A006E816930d9f55DF0a72a13; | ||
address constant GAUGE_2 = 0xc7e5FE004416A96Cb2C7D6440c28aE92262f7695; | ||
address constant LM_MULTISIG = 0xc38c5f97B34E175FFd35407fc91a937300E33860; | ||
address constant AUTHORIZER_ADAPTER = 0xAB093cd16e765b5B23D34030aaFaF026558e0A19; | ||
address constant TEST_TOKEN_WHALE = 0xF977814e90dA44bFA03b6295A0616a897441aceC; | ||
|
||
// token address constants | ||
address constant USDT = 0xc2132D05D31c914a87C6611C10748AEb04B58e8F; | ||
address constant USDC = 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174; | ||
|
||
// agents | ||
address constant KEEPER = address(5); | ||
|
||
address[] KEEPER_ADDRESSES = new address[](1); | ||
|
||
// dummy constants | ||
uint256 MIN_WAIT_PERIOD_SECONDS = 1 days; | ||
uint256 MAX_INJECTION_AMOUNT = 1_000e18; | ||
address OWNER = address(56565); | ||
|
||
event InjectorCreated( | ||
address indexed injector, address[] keeperAddresses, address injectTokenAddress, address owner | ||
); | ||
|
||
function setUp() public { | ||
vm.createSelectFork("polygon"); | ||
|
||
injector = new ChildChainGaugeInjectorV2(); | ||
factory = new ChildChainGaugeInjectorV2Factory(address(injector)); | ||
|
||
assert(factory.implementation() == address(injector)); | ||
} | ||
|
||
function _deployDummyInjector() internal returns (address injectorDeployed_) { | ||
KEEPER_ADDRESSES[0] = KEEPER; | ||
|
||
// check: event emitted | ||
vm.expectEmit(false, true, true, true); // @note topic0 is not checkeds | ||
emit InjectorCreated(address(0), KEEPER_ADDRESSES, USDT, OWNER); | ||
|
||
injectorDeployed_ = | ||
factory.createInjector(KEEPER_ADDRESSES, MIN_WAIT_PERIOD_SECONDS, USDT, MAX_INJECTION_AMOUNT, OWNER); | ||
} | ||
|
||
function _enableInjectorAsDistributor(address _injector) internal { | ||
IChildChainGauge gaugeFirst = IChildChainGauge(GAUGE); | ||
IChildChainGauge gaugeSecond = IChildChainGauge(GAUGE_2); | ||
|
||
vm.prank(gaugeFirst.authorizer_adaptor()); | ||
gaugeFirst.add_reward(USDT, _injector); | ||
vm.prank(gaugeSecond.authorizer_adaptor()); | ||
gaugeSecond.add_reward(USDT, _injector); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.25; | ||
|
||
import {BaseFixture} from "./BaseFixture.sol"; | ||
|
||
import {ChildChainGaugeInjectorV2} from "../contracts/ChildChainGaugeInjectorV2.sol"; | ||
|
||
contract FactoryTest is BaseFixture { | ||
function testCreateInjector() public { | ||
// 1. create a new injector via factory | ||
address injectorDeployed = _deployDummyInjector(); | ||
ChildChainGaugeInjectorV2 injectorFactoryDeployed = ChildChainGaugeInjectorV2(injectorDeployed); | ||
|
||
// 2. asserts: | ||
// 2.1. check `getDeployedInjectors` returns the correct number of injectors | ||
address[] memory injectorsDeployed = factory.getDeployedInjectors(); | ||
assertEq(injectorsDeployed.length, 1); | ||
assertEq(injectorsDeployed[0], injectorDeployed); | ||
|
||
// 2.2. check params of the injector correctness at deployment time | ||
assertEq(injectorFactoryDeployed.owner(), OWNER); | ||
assertEq(injectorFactoryDeployed.getKeeperAddresses()[0], KEEPER); | ||
assertEq(injectorFactoryDeployed.MinWaitPeriodSeconds(), MIN_WAIT_PERIOD_SECONDS); | ||
assertEq(injectorFactoryDeployed.InjectTokenAddress(), USDT); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@note here that this flag
--multi
it is for multichain deployments