packages/solidity-devops/src/reader/DataReader.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.12;
pragma experimental ABIEncoderV2;
import {PathFinder} from "../base/PathFinder.sol";
import {StringUtils} from "../libs/StringUtils.sol";
import {stdJson} from "forge-std/StdJson.sol";
abstract contract DataReader is PathFinder {
using stdJson for string;
using StringUtils for *;
// ════════════════════════════════════════════ GENERIC DATA READS ═════════════════════════════════════════════════
/// @notice Reads a file from the filesystem and returns its content.
/// @dev Returns an empty string or reverts if the file is not found based on the flag.
function readFile(string memory path, bool revertIfNotFound) internal view returns (string memory) {
try vm.readFile(path) returns (string memory content) {
return content;
} catch {
if (revertIfNotFound) revert(StringUtils.concat("DataReader: failed to read file: ", path));
return "";
}
}
/// @notice Tries to read the full contract artifact JSON generated by forge.
/// @dev Returns an empty string or reverts if the artifact is not found based on the flag.
function readContractArtifact(
string memory contractName,
bool revertIfNotFound
)
internal
view
returns (string memory)
{
return readFile(getArtifactFN(contractName), revertIfNotFound);
}
/// @notice Returns the saved deployment artifact JSON for a contract.
/// @dev Returns an empty string or reverts if the artifact is not found based on the flag.
function readDeploymentArtifact(
string memory chain,
string memory contractName,
bool revertIfNotFound
)
internal
view
returns (string memory artifact)
{
return readFile(getDeploymentFN(chain, contractName), revertIfNotFound);
}
/// @notice Returns the deployment configuration JSON for a contract.
/// @dev Returns an empty string or reverts if the artifact is not found based on the flag.
function readDeployConfig(
string memory chain,
string memory contractName,
bool revertIfNotFound
)
internal
view
returns (string memory deployConfig)
{
return readFile(getDeployConfigFN(chain, contractName), revertIfNotFound);
}
/// @notice Returns the global deployment configuration JSON.
/// @dev Returns an empty string or reverts if the artifact is not found based on the flag.
function readGlobalDeployConfig(
string memory contractName,
string memory environment,
bool revertIfNotFound
)
internal
view
returns (string memory deployConfig)
{
return readFile(getGlobalDeployConfigFN(contractName, environment), revertIfNotFound);
}
/// @notice Returns the global deployment configuration JSON for the production environment.
/// @dev Returns an empty string or reverts if the artifact is not found based on the flag.
function readGlobalDeployProdConfig(
string memory contractName,
bool revertIfNotFound
)
internal
view
returns (string memory deployConfig)
{
return readFile(getGlobalDeployConfigFN(contractName, ENVIRONMENT_PROD), revertIfNotFound);
}
// ════════════════════════════════════════════ SPECIFIC DATA READS ════════════════════════════════════════════════
/// @notice Returns the contract bytecode extracted from the artifact generated by forge.
/// @dev Returns an empty string or reverts if the artifact is not found based on the flag.
function getContractBytecode(
string memory contractName,
bool revertIfNotFound
)
internal
view
returns (bytes memory bytecode)
{
string memory artifact = readContractArtifact(contractName, revertIfNotFound);
if (artifact.length() == 0) return "";
return artifact.readBytes(".bytecode.object");
}
/// @notice Returns the deployment address for a contract on a given chain.
/// @dev Returns address(0) or reverts if the artifact is not found based on the flag.
function getDeploymentAddress(
string memory chain,
string memory contractName,
bool revertIfNotFound
)
internal
view
returns (address)
{
// This will revert if the artifact is not found and flag is set to true
string memory deploymentArtifact = readDeploymentArtifact(chain, contractName, revertIfNotFound);
if (deploymentArtifact.length() == 0) return address(0);
return deploymentArtifact.readAddress(".address");
}
/// @notice Checks if a contract is deployed on a given chain without reverting.
function isDeployed(string memory chain, string memory contractName) internal view returns (bool) {
return getDeploymentAddress(chain, contractName, false) != address(0);
}
}