Beginner FriendlyDeFiFoundry
100 EXP
View results
Submission Details
Severity: low
Invalid

Incorrect script setup in `Deployer.s.sol`

Vulnerability Details

Deploy script Deploy.s.sol is set up incorrectly:

  • ISSUE 1: the deployment of HelperConfig is broadcasted,

  • ISSUE 2: Deploy::run does not return the addresses of the deployed contracts,

  • ISSUE 3: It relies on a HelperConfig file that does not specify the correct USDC addresses on the different live chains

Impact

  • ISSUE 1: HelperConfig is also deployed on the blockchain, which is a waste of gas

  • ISSUE 2: using Deploy::run will be impractical in tests,

  • ISSUE 3: the protocol will not work if deployed to any of the specified live chains

Tools Used

Manual review, Foundry.

Recommendations

Perform the following modifications:

  • Deployer.s.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import { Script, console2 } from "lib/forge-std/src/Script.sol";
import { IERC20 } from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import { HelperConfig } from "script/HelperConfig.s.sol";
import { Kernel, Actions, Role } from "src/Kernel.sol";
import { CrimeMoney } from "src/CrimeMoney.sol";
import { WeaponShelf } from "src/modules/WeaponShelf.sol";
import { MoneyShelf } from "src/modules/MoneyShelf.sol";
import { Laundrette } from "src/policies/Laundrette.sol";
contract Deployer is Script {
address public godFather;
+ Kernel public kernel;
+ IERC20 public usdc;
+ CrimeMoney public crimeMoney;
+ WeaponShelf public weaponShelf;
+ MoneyShelf public moneyShelf;
+ Laundrette public laundrette;
- function run() public {
+ function run() public returns (Kernel, IERC20, CrimeMoney, WeaponShelf, MoneyShelf, Laundrette) {
+ // Instantiate HelperConfig outside the broadcast block
+ HelperConfig helperConfig = new HelperConfig();
+ usdc = IERC20(helperConfig.getActiveNetworkConfig().usdc);
vm.startBroadcast();
- deploy();
+ _deploy(IERC20 usdc);
vm.stopBroadcast();
+ return (kernel, usdc, crimeMoney, weaponShelf, moneyShelf, laundrette);
}
- function deploy() public returns (Kernel, IERC20, CrimeMoney, WeaponShelf, MoneyShelf, Laundrette) {
+ function _deploy(IERC20 usdc) internal returns (Kernel, IERC20, CrimeMoney, WeaponShelf, MoneyShelf, Laundrette) {
godFather = msg.sender;
- // Deploy USDC mock
- HelperConfig helperConfig = new HelperConfig();
- IERC20 usdc = IERC20(helperConfig.getActiveNetworkConfig().usdc);
Kernel kernel = new Kernel();
CrimeMoney crimeMoney = new CrimeMoney(kernel);
WeaponShelf weaponShelf = new WeaponShelf(kernel);
MoneyShelf moneyShelf = new MoneyShelf(kernel, usdc, crimeMoney);
Laundrette laundrette = new Laundrette(kernel);
kernel.grantRole(Role.wrap("moneyshelf"), address(moneyShelf));
kernel.executeAction(Actions.InstallModule, address(weaponShelf));
kernel.executeAction(Actions.InstallModule, address(moneyShelf));
kernel.executeAction(Actions.ActivatePolicy, address(laundrette));
kernel.executeAction(Actions.ChangeAdmin, address(laundrette));
kernel.executeAction(Actions.ChangeExecutor, godFather);
return (kernel, usdc, crimeMoney, weaponShelf, moneyShelf, laundrette);
}
}
  • HelperConfig.s.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import { Script } from "lib/forge-std/src/Script.sol";
import { console2 } from "lib/forge-std/src/console2.sol";
import { Deployer } from "script/Deployer.s.sol";
import { MockUSDC } from "test/mocks/MockUSDC.sol";
contract HelperConfig is Script {
/*//////////////////////////////////////////////////////////////
ERRORS
//////////////////////////////////////////////////////////////*/
error HelperConfig__InvalidChainId();
/*//////////////////////////////////////////////////////////////
TYPES
//////////////////////////////////////////////////////////////*/
struct NetworkConfig {
address usdc;
}
/*//////////////////////////////////////////////////////////////
STATE VARIABLES
//////////////////////////////////////////////////////////////*/
uint256 constant ETH_MAINNET_CHAIN_ID = 1;
uint256 constant ETH_SEPOLIA_CHAIN_ID = 11_155_111;
uint256 constant ZKSYNC_MAINNET_CHAIN_ID = 324;
uint256 constant ZKSYNC_SEPOLIA_CHAIN_ID = 300;
uint256 constant POLYGON_MAINNET_CHAIN_ID = 137;
uint256 constant POLYGON_MUMBAI_CHAIN_ID = 80_001;
// Local network state variables
NetworkConfig public localNetworkConfig;
mapping(uint256 chainId => NetworkConfig) public networkConfigs;
/*//////////////////////////////////////////////////////////////
FUNCTIONS
//////////////////////////////////////////////////////////////*/
constructor() {
networkConfigs[ETH_MAINNET_CHAIN_ID] = getEthMainnetConfig();
- networkConfigs[ETH_SEPOLIA_CHAIN_ID] = getZkSyncSepoliaConfig();
+ networkConfigs[ETH_SEPOLIA_CHAIN_ID] = getEthSepoliaConfig();
networkConfigs[ZKSYNC_MAINNET_CHAIN_ID] = getZkSyncConfig();
networkConfigs[ZKSYNC_SEPOLIA_CHAIN_ID] = getZkSyncSepoliaConfig();
networkConfigs[POLYGON_MAINNET_CHAIN_ID] = getPolygonMainnetConfig();
networkConfigs[POLYGON_MUMBAI_CHAIN_ID] = getPolygonMumbaiConfig();
}
function getConfigByChainId(uint256 chainId) public returns (NetworkConfig memory) {
if (networkConfigs[chainId].usdc != address(0)) {
return networkConfigs[chainId];
} else {
return getOrCreateAnvilEthConfig();
}
}
function getActiveNetworkConfig() public returns (NetworkConfig memory) {
return getConfigByChainId(block.chainid);
}
/*//////////////////////////////////////////////////////////////
CONFIGS
//////////////////////////////////////////////////////////////*/
function getEthMainnetConfig() public pure returns (NetworkConfig memory) {
- return NetworkConfig({ usdc: address(1) });
+ return NetworkConfig({ usdc: address(0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) });
}
+ function getEthSepoliaConfig() public pure returns (NetworkConfig memory) {
+ return NetworkConfig({ usdc: address(0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238) });
+ }
function getZkSyncConfig() public pure returns (NetworkConfig memory) {
- return NetworkConfig({ usdc: address(1) });
+ return NetworkConfig({ usdc: address(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4) });
}
function getZkSyncSepoliaConfig() public pure returns (NetworkConfig memory) {
- return NetworkConfig({ usdc: address(1) });
+ return NetworkConfig({ usdc: address(0xAe045DE5638162fa134807Cb558E15A3F5A7F853) });
}
function getPolygonMainnetConfig() public pure returns (NetworkConfig memory) {
- return NetworkConfig({ usdc: address(1) });
+ return NetworkConfig({ usdc: address(0x2791bca1f2de4661ed88a30c99a7a9449aa84174) });
}
function getPolygonMumbaiConfig() public pure returns (NetworkConfig memory) {
- return NetworkConfig({ usdc: address(1) });
+ return NetworkConfig({ usdc: address(0xe6b8a5CF854791412c1f6EFC7CAf629f5Df1c747) });
}
/*//////////////////////////////////////////////////////////////
LOCAL CONFIG
//////////////////////////////////////////////////////////////*/
function getOrCreateAnvilEthConfig() public returns (NetworkConfig memory) {
if (localNetworkConfig.usdc != address(0)) {
return localNetworkConfig;
}
console2.log(unicode"⚠️ You have deployed a mock conract!");
console2.log("Make sure this was intentional");
vm.prank(Deployer(msg.sender).godFather());
address mockUsdc = _deployMocks();
localNetworkConfig = NetworkConfig({ usdc: mockUsdc });
return localNetworkConfig;
}
/*
* Add your mocks, deploy and return them here for your local anvil network
*/
function _deployMocks() internal returns (address) {
MockUSDC usdc = new MockUSDC();
return address(usdc);
}
}
Updates

Lead Judging Commences

n0kto Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.