fix(DeployContracts): deploy multicall on local node (#82)
This fixes a bug that multicall isn't available on a local node. This commit ensures we deploy it. It also outputs multicall addresses for Goerli and Optimism, as those will be needed when the app is deployed to production.
This commit is contained in:
parent
c8c01b0423
commit
aa006ba177
|
@ -0,0 +1,99 @@
|
||||||
|
/**
|
||||||
|
* Submitted for verification at Optimistic.Etherscan.io on 2022-05-14
|
||||||
|
*/
|
||||||
|
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
pragma solidity >=0.5.0;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
/// @title Multicall2 - Aggregate results from multiple read-only function calls
|
||||||
|
/// @author Michael Elliot <mike@makerdao.com>
|
||||||
|
/// @author Joshua Levine <joshua@makerdao.com>
|
||||||
|
/// @author Nick Johnson <arachnid@notdot.net>
|
||||||
|
|
||||||
|
contract Multicall2 {
|
||||||
|
struct Call {
|
||||||
|
address target;
|
||||||
|
bytes callData;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Result {
|
||||||
|
bool success;
|
||||||
|
bytes returnData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) {
|
||||||
|
blockNumber = block.number;
|
||||||
|
returnData = new bytes[](calls.length);
|
||||||
|
for (uint256 i = 0; i < calls.length; i++) {
|
||||||
|
(bool success, bytes memory ret) = calls[i].target.call(calls[i].callData);
|
||||||
|
require(success, "Multicall aggregate: call failed");
|
||||||
|
returnData[i] = ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function blockAndAggregate(Call[] memory calls)
|
||||||
|
public
|
||||||
|
returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData)
|
||||||
|
{
|
||||||
|
(blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) {
|
||||||
|
blockHash = blockhash(blockNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBlockNumber() public view returns (uint256 blockNumber) {
|
||||||
|
blockNumber = block.number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentBlockCoinbase() public view returns (address coinbase) {
|
||||||
|
coinbase = block.coinbase;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentBlockDifficulty() public view returns (uint256 difficulty) {
|
||||||
|
difficulty = block.difficulty;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) {
|
||||||
|
gaslimit = block.gaslimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentBlockTimestamp() public view returns (uint256 timestamp) {
|
||||||
|
timestamp = block.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEthBalance(address addr) public view returns (uint256 balance) {
|
||||||
|
balance = addr.balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLastBlockHash() public view returns (bytes32 blockHash) {
|
||||||
|
blockHash = blockhash(block.number - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tryAggregate(bool requireSuccess, Call[] memory calls) public returns (Result[] memory returnData) {
|
||||||
|
returnData = new Result[](calls.length);
|
||||||
|
for (uint256 i = 0; i < calls.length; i++) {
|
||||||
|
(bool success, bytes memory ret) = calls[i].target.call(calls[i].callData);
|
||||||
|
|
||||||
|
if (requireSuccess) {
|
||||||
|
require(success, "Multicall2 aggregate: call failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
returnData[i] = Result(success, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function tryBlockAndAggregate(
|
||||||
|
bool requireSuccess,
|
||||||
|
Call[] memory calls
|
||||||
|
)
|
||||||
|
public
|
||||||
|
returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData)
|
||||||
|
{
|
||||||
|
blockNumber = block.number;
|
||||||
|
blockHash = blockhash(block.number);
|
||||||
|
returnData = tryAggregate(requireSuccess, calls);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
pragma solidity ^0.8.19;
|
pragma solidity ^0.8.19;
|
||||||
|
|
||||||
import { Script } from "forge-std/Script.sol";
|
import { console } from "forge-std/Test.sol";
|
||||||
import { MiniMeToken } from "@vacp2p/minime/contracts/MiniMeToken.sol";
|
import { MiniMeToken } from "@vacp2p/minime/contracts/MiniMeToken.sol";
|
||||||
import { DeploymentConfig } from "./DeploymentConfig.s.sol";
|
import { DeploymentConfig } from "./DeploymentConfig.s.sol";
|
||||||
import { BaseScript } from "./Base.s.sol";
|
import { BaseScript } from "./Base.s.sol";
|
||||||
|
@ -56,6 +56,7 @@ contract DeployContracts is BaseScript {
|
||||||
featuredVotingContract.setDirectory(directoryContract);
|
featuredVotingContract.setDirectory(directoryContract);
|
||||||
vm.stopBroadcast();
|
vm.stopBroadcast();
|
||||||
|
|
||||||
|
console.log("contract Multicall2", deploymentConfig.getMulticallAddress());
|
||||||
return (minimeToken, directoryContract, votingContract, featuredVotingContract);
|
return (minimeToken, directoryContract, votingContract, featuredVotingContract);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,12 @@ pragma solidity ^0.8.19;
|
||||||
import { Script } from "forge-std/Script.sol";
|
import { Script } from "forge-std/Script.sol";
|
||||||
import { MiniMeTokenFactory } from "@vacp2p/minime/contracts/MiniMeTokenFactory.sol";
|
import { MiniMeTokenFactory } from "@vacp2p/minime/contracts/MiniMeTokenFactory.sol";
|
||||||
import { MiniMeToken } from "@vacp2p/minime/contracts/MiniMeToken.sol";
|
import { MiniMeToken } from "@vacp2p/minime/contracts/MiniMeToken.sol";
|
||||||
|
import { Multicall2 } from "../contracts/Multicall2.sol";
|
||||||
|
|
||||||
contract DeploymentConfig is Script {
|
contract DeploymentConfig is Script {
|
||||||
|
|
||||||
|
error DeploymentConfig__InvalidMulticallAddress();
|
||||||
|
|
||||||
NetworkConfig public activeNetworkConfig;
|
NetworkConfig public activeNetworkConfig;
|
||||||
|
|
||||||
struct NetworkConfig {
|
struct NetworkConfig {
|
||||||
|
@ -31,11 +35,18 @@ contract DeploymentConfig is Script {
|
||||||
|
|
||||||
address public deployer;
|
address public deployer;
|
||||||
|
|
||||||
|
address private multicallAddress;
|
||||||
|
|
||||||
// solhint-disable-next-line var-name-mixedcase
|
// solhint-disable-next-line var-name-mixedcase
|
||||||
address internal SNT_ADDRESS_GOERLI = 0x3D6AFAA395C31FCd391fE3D562E75fe9E8ec7E6a;
|
address internal SNT_ADDRESS_GOERLI = 0x3D6AFAA395C31FCd391fE3D562E75fe9E8ec7E6a;
|
||||||
// solhint-disable-next-line var-name-mixedcase
|
// solhint-disable-next-line var-name-mixedcase
|
||||||
address internal SNT_ADDRESS_MAINNET = 0x744d70FDBE2Ba4CF95131626614a1763DF805B9E;
|
address internal SNT_ADDRESS_MAINNET = 0x744d70FDBE2Ba4CF95131626614a1763DF805B9E;
|
||||||
|
|
||||||
|
// solhint-disable-next-line var-name-mixedcase
|
||||||
|
address internal MULTICALL_ADDRESS_GOERLI = 0x77dCa2C955b15e9dE4dbBCf1246B4B85b651e50e;
|
||||||
|
// solhint-disable-next-line var-name-mixedcase
|
||||||
|
address internal MULTICALL_ADDRESS_OPTIMISM = 0xeAa6877139d436Dc6d1f75F3aF15B74662617B2C;
|
||||||
|
|
||||||
constructor(address _broadcaster) {
|
constructor(address _broadcaster) {
|
||||||
deployer = _broadcaster;
|
deployer = _broadcaster;
|
||||||
if (block.chainid == 1) {
|
if (block.chainid == 1) {
|
||||||
|
@ -62,7 +73,12 @@ contract DeploymentConfig is Script {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getGoerliEthConfig() public view returns (NetworkConfig memory) {
|
function getGoerliEthConfig() public returns (NetworkConfig memory) {
|
||||||
|
// Actually, it'd be nicer to have `multicallAddress` be part of `NetworkConfig`,
|
||||||
|
// however, adding another field to the struct causes us to run into the
|
||||||
|
// "stack too deep" error during compilation, hence, we're using an additional
|
||||||
|
// property on the contract to access the value later from there.
|
||||||
|
multicallAddress = MULTICALL_ADDRESS_GOERLI;
|
||||||
return NetworkConfig({
|
return NetworkConfig({
|
||||||
votingLengthInSeconds: FOUR_MINS_IN_SECONDS,
|
votingLengthInSeconds: FOUR_MINS_IN_SECONDS,
|
||||||
votingVerificationLengthInSeconds: TWO_MINS_IN_SECONDS,
|
votingVerificationLengthInSeconds: TWO_MINS_IN_SECONDS,
|
||||||
|
@ -88,8 +104,16 @@ contract DeploymentConfig is Script {
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
minimeToken.generateTokens(deployer, 100_000_000 ether);
|
minimeToken.generateTokens(deployer, 100_000_000 ether);
|
||||||
|
|
||||||
|
Multicall2 multicall = new Multicall2();
|
||||||
vm.stopBroadcast();
|
vm.stopBroadcast();
|
||||||
|
|
||||||
|
// Actually, it'd be nicer to have `multicallAddress` be part of `NetworkConfig`,
|
||||||
|
// however, adding another field to the struct causes us to run into the
|
||||||
|
// "stack too deep" error during compilation, hence, we're using an additional
|
||||||
|
// property on the contract to access the value later from there.
|
||||||
|
multicallAddress = address(multicall);
|
||||||
|
|
||||||
return NetworkConfig({
|
return NetworkConfig({
|
||||||
votingLengthInSeconds: FOUR_MINS_IN_SECONDS,
|
votingLengthInSeconds: FOUR_MINS_IN_SECONDS,
|
||||||
votingVerificationLengthInSeconds: TWO_MINS_IN_SECONDS,
|
votingVerificationLengthInSeconds: TWO_MINS_IN_SECONDS,
|
||||||
|
@ -101,4 +125,11 @@ contract DeploymentConfig is Script {
|
||||||
voteToken: address(minimeToken)
|
voteToken: address(minimeToken)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getMulticallAddress() public view returns (address) {
|
||||||
|
if (multicallAddress == address(0)) {
|
||||||
|
revert DeploymentConfig__InvalidMulticallAddress();
|
||||||
|
}
|
||||||
|
return multicallAddress;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue