Skip to content

Commit

Permalink
Merge pull request #4 from base-fundy/razvan
Browse files Browse the repository at this point in the history
Razvan
  • Loading branch information
MihRazvan authored Mar 29, 2024
2 parents 3f17584 + 1a00314 commit 2e92e16
Show file tree
Hide file tree
Showing 18 changed files with 11,776 additions and 774 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "packages/foundry/lib/solidity-bytes-utils"]
path = packages/foundry/lib/solidity-bytes-utils
url = https://github.com/gnsps/solidity-bytes-utils
url = https://github.com/GNSPS/solidity-bytes-utils
3 changes: 0 additions & 3 deletions packages/foundry/.env.example

This file was deleted.

79 changes: 79 additions & 0 deletions packages/foundry/broadcast/Deploy.s.sol/84532/run-1711703392.json

Large diffs are not rendered by default.

155 changes: 155 additions & 0 deletions packages/foundry/broadcast/Deploy.s.sol/84532/run-1711703398.json

Large diffs are not rendered by default.

79 changes: 79 additions & 0 deletions packages/foundry/broadcast/Deploy.s.sol/84532/run-1711703681.json

Large diffs are not rendered by default.

155 changes: 155 additions & 0 deletions packages/foundry/broadcast/Deploy.s.sol/84532/run-1711703688.json

Large diffs are not rendered by default.

155 changes: 155 additions & 0 deletions packages/foundry/broadcast/Deploy.s.sol/84532/run-latest.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/foundry/deployments/31337.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"networkName": "Anvil"
}
3 changes: 3 additions & 0 deletions packages/foundry/deployments/84532.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"networkName": "baseSepolia"
}
1 change: 1 addition & 0 deletions packages/foundry/lib/solidity-bytes-utils
Submodule solidity-bytes-utils added at e0115c
7 changes: 3 additions & 4 deletions packages/foundry/remappings.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
@openzeppelin/contracts/=../../node_modules/@openzeppelin/contracts/
@sablier/v2-core/=../../node_modules/@sablier/v2-core/
@sablier/v2-periphery/=../../node_modules/@sablier/v2-periphery/
@prb/math/=../../node_modules/@prb/math/
@forge-std/=lib/forge-std/
@openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/
@openzeppelin/=lib/openzeppelin-contracts/
39 changes: 39 additions & 0 deletions packages/foundry/script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "../contracts/MockUSDC.sol";
import "../contracts/FundFactory.sol";
import "../contracts/FundingRound.sol";
import "forge-std/Script.sol";
import "./DeployHelpers.s.sol";

contract DeployScript is ScaffoldETHDeploy {
error InvalidPrivateKey(string);

function run() external {
uint256 deployerPrivateKey = setupLocalhostEnv();
if (deployerPrivateKey == 0) {
revert InvalidPrivateKey(
"You don't have a deployer account. Make sure you have set DEPLOYER_PRIVATE_KEY in .env or use `yarn generate` to generate a new random account"
);
}
vm.startBroadcast(deployerPrivateKey);
MockUSDC mockUSDC = new MockUSDC();
console.log("MockUSDC deployed at:", address(mockUSDC));

FundFactory fundFactory = new FundFactory(address(mockUSDC));
console.log("FundFactory deployed at:", address(fundFactory));

fundFactory.createFundingRound();
console.log("Funding round created through FundFactory");

vm.stopBroadcast();
/**
* This function generates the file containing the contracts Abi definitions.
* These definitions are used to derive the types needed in the custom scaffold-eth hooks, for example.
* This function should be called last.
*/
exportDeployments();
}
function test() public {}
}
82 changes: 82 additions & 0 deletions packages/foundry/script/DeployHelpers.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
pragma solidity ^0.8.19;

import "forge-std/Script.sol";
import "forge-std/Vm.sol";

contract ScaffoldETHDeploy is Script {
error InvalidChain();

struct Deployment {
string name;
address addr;
}

string root;
string path;
Deployment[] public deployments;

function setupLocalhostEnv()
internal
returns (uint256 localhostPrivateKey)
{
if (block.chainid == 31337) {
root = vm.projectRoot();
path = string.concat(root, "/localhost.json");
string memory json = vm.readFile(path);
bytes memory mnemonicBytes = vm.parseJson(json, ".wallet.mnemonic");
string memory mnemonic = abi.decode(mnemonicBytes, (string));
return vm.deriveKey(mnemonic, 0);
} else {
return vm.envUint("DEPLOYER_PRIVATE_KEY");
}
}

function exportDeployments() internal {
// fetch already existing contracts
root = vm.projectRoot();
path = string.concat(root, "/deployments/");
string memory chainIdStr = vm.toString(block.chainid);
path = string.concat(path, string.concat(chainIdStr, ".json"));

string memory jsonWrite;

uint256 len = deployments.length;

for (uint256 i = 0; i < len; i++) {
vm.serializeString(
jsonWrite,
vm.toString(deployments[i].addr),
deployments[i].name
);
}

string memory chainName;

try this.getChain() returns (Chain memory chain) {
chainName = chain.name;
} catch {
chainName = findChainName();
}
jsonWrite = vm.serializeString(jsonWrite, "networkName", chainName);
vm.writeJson(jsonWrite, path);
}

function getChain() public returns (Chain memory) {
return getChain(block.chainid);
}

function findChainName() public returns (string memory) {
uint256 thisChainId = block.chainid;
string[2][] memory allRpcUrls = vm.rpcUrls();
for (uint256 i = 0; i < allRpcUrls.length; i++) {
try vm.createSelectFork(allRpcUrls[i][1]) {
if (block.chainid == thisChainId) {
return allRpcUrls[i][0];
}
} catch {
continue;
}
}
revert InvalidChain();
}
}
77 changes: 77 additions & 0 deletions packages/foundry/script/ListAccount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const dotenv = require("dotenv");
dotenv.config();
const path = require("path");
const { ethers, Wallet } = require("ethers");
const QRCode = require("qrcode");
const fs = require("fs");
const toml = require("toml");

const ALCHEMY_API_KEY =
process.env.ALCHEMY_API_KEY || "oKxs-03sij-U_N0iOlrSsZFr29-IqbuF";

async function getBalanceForEachNetwork(address) {
try {
// Read the foundry.toml file
const foundryTomlPath = path.join(__dirname, "..", "foundry.toml");
const tomlString = fs.readFileSync(foundryTomlPath, "utf-8");

// Parse the tomlString to get the JS object representation
const parsedToml = toml.parse(tomlString);

// Extract rpc_endpoints from parsedToml
const rpcEndpoints = parsedToml.rpc_endpoints;

// Replace placeholders in the rpc_endpoints section
function replaceENVAlchemyKey(input) {
return input.replace("${ALCHEMY_API_KEY}", ALCHEMY_API_KEY);
}

for (const networkName in rpcEndpoints) {
if (networkName === "localhost" || networkName === "default_network")
continue;

const networkUrl = replaceENVAlchemyKey(rpcEndpoints[networkName]);

try {
const provider = new ethers.providers.JsonRpcProvider(networkUrl);
const balance = await provider.getBalance(address);
console.log("--", networkName, "-- 📡");
console.log(" balance:", +ethers.utils.formatEther(balance));
console.log(
" nonce:",
+(await provider.getTransactionCount(address))
);
} catch (e) {
console.log("Can't connect to network", networkName);
console.log();
}
}
} catch (error) {
console.error("Error reading foundry.toml:", error);
}
}
async function main() {
const privateKey = process.env.DEPLOYER_PRIVATE_KEY;

if (!privateKey) {
console.log(
"🚫️ You don't have a deployer account. Run `yarn generate` first"
);
return;
}

// Get account from private key.
const wallet = new Wallet(privateKey);
const address = wallet.address;
console.log(
await QRCode.toString(address, { type: "terminal", small: true })
);
console.log("Public address:", address, "\n");

await getBalanceForEachNetwork(address);
}

main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
156 changes: 156 additions & 0 deletions packages/foundry/script/VerifyAll.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "forge-std/Script.sol";
import "forge-std/Vm.sol";
import "solidity-bytes-utils/BytesLib.sol";

/**
* @dev Temp Vm implementation
* @notice calls the tryffi function on the Vm contract
* @notice will be deleted once the forge/std is updated
*/
struct FfiResult {
int32 exit_code;
bytes stdout;
bytes stderr;
}

interface tempVm {
function tryFfi(string[] calldata) external returns (FfiResult memory);
}

contract VerifyAll is Script {
uint96 currTransactionIdx;

function run() external {
string memory root = vm.projectRoot();
string memory path = string.concat(
root,
"/broadcast/Deploy.s.sol/",
vm.toString(block.chainid),
"/run-latest.json"
);
string memory content = vm.readFile(path);

while (this.nextTransaction(content)) {
_verifyIfContractDeployment(content);
currTransactionIdx++;
}
}

function _verifyIfContractDeployment(string memory content) internal {
string memory txType = abi.decode(
vm.parseJson(
content,
searchStr(currTransactionIdx, "transactionType")
),
(string)
);
if (keccak256(bytes(txType)) == keccak256(bytes("CREATE"))) {
_verifyContract(content);
}
}

function _verifyContract(string memory content) internal {
string memory contractName = abi.decode(
vm.parseJson(
content,
searchStr(currTransactionIdx, "contractName")
),
(string)
);
address contractAddr = abi.decode(
vm.parseJson(
content,
searchStr(currTransactionIdx, "contractAddress")
),
(address)
);
bytes memory deployedBytecode = abi.decode(
vm.parseJson(
content,
searchStr(currTransactionIdx, "transaction.data")
),
(bytes)
);
bytes memory compiledBytecode = abi.decode(
vm.parseJson(
_getCompiledBytecode(contractName),
".bytecode.object"
),
(bytes)
);
bytes memory constructorArgs = BytesLib.slice(
deployedBytecode,
compiledBytecode.length,
deployedBytecode.length - compiledBytecode.length
);

string[] memory inputs = new string[](9);
inputs[0] = "forge";
inputs[1] = "verify-contract";
inputs[2] = vm.toString(contractAddr);
inputs[3] = contractName;
inputs[4] = "--chain";
inputs[5] = vm.toString(block.chainid);
inputs[6] = "--constructor-args";
inputs[7] = vm.toString(constructorArgs);
inputs[8] = "--watch";

FfiResult memory f = tempVm(address(vm)).tryFfi(inputs);

if (f.stderr.length != 0) {
console.logString(
string.concat(
"Submitting verification for contract: ",
vm.toString(contractAddr)
)
);
console.logString(string(f.stderr));
} else {
console.logString(string(f.stdout));
}
return;
}

function nextTransaction(
string memory content
) external view returns (bool) {
try this.getTransactionFromRaw(content, currTransactionIdx) {
return true;
} catch {
return false;
}
}

function _getCompiledBytecode(
string memory contractName
) internal view returns (string memory compiledBytecode) {
string memory root = vm.projectRoot();
string memory path = string.concat(
root,
"/out/",
contractName,
".sol/",
contractName,
".json"
);
compiledBytecode = vm.readFile(path);
}

function getTransactionFromRaw(
string memory content,
uint96 idx
) external pure {
abi.decode(vm.parseJson(content, searchStr(idx, "hash")), (bytes32));
}

function searchStr(
uint96 idx,
string memory searchKey
) internal pure returns (string memory) {
return
string.concat(".transactions[", vm.toString(idx), "].", searchKey);
}
}
Loading

0 comments on commit 2e92e16

Please sign in to comment.