mirror of
https://github.com/luxfi/uma.git
synced 2026-07-26 21:09:10 +00:00
feat(core): add tasks to manage artifacts and deployments (#3229)
This commit is contained in:
@@ -12,3 +12,5 @@ dist
|
||||
cache
|
||||
types
|
||||
contract-types
|
||||
generated
|
||||
typechain
|
||||
|
||||
@@ -17,6 +17,8 @@ antora.yml
|
||||
.eslintcache
|
||||
.idea
|
||||
optimism
|
||||
generated
|
||||
typechain
|
||||
|
||||
# GAE deployment files and directories for GAE deployments.
|
||||
app.yaml
|
||||
|
||||
@@ -11,3 +11,5 @@ cache
|
||||
.github
|
||||
types
|
||||
contract-types
|
||||
generated
|
||||
typechain
|
||||
|
||||
+12
-9
@@ -4,9 +4,9 @@
|
||||
"description": "UMA monorepo containing protocol packages",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"bootstrap": "npx lerna bootstrap",
|
||||
"lint": "npm run eslint && npm run prettier -- --list-different",
|
||||
"lint-fix": "npm run eslint -- --fix && npm run prettier -- --write",
|
||||
"bootstrap": "yarn",
|
||||
"lint": "yarn eslint && yarn prettier --list-different",
|
||||
"lint-fix": "yarn eslint --fix && yarn prettier --write",
|
||||
"eslint": "eslint './**/*.js' './**/*.ts'",
|
||||
"prettier": "prettier './**/*.js' './**/*.sol' './**/*.md' './**/*.ts'",
|
||||
"test": "lerna run --stream --concurrency=4 test",
|
||||
@@ -31,7 +31,7 @@
|
||||
"devDependencies": {
|
||||
"@antora/cli": "^2.1.2",
|
||||
"@antora/site-generator-default": "^2.1.2",
|
||||
"@typechain/ethers-v5": "^6.0.5",
|
||||
"@typechain/ethers-v5": "^7.0.1",
|
||||
"@typescript-eslint/eslint-plugin": "^4.14.1",
|
||||
"@typescript-eslint/parser": "^4.14.1",
|
||||
"babel-eslint": "10.0.1",
|
||||
@@ -52,12 +52,13 @@
|
||||
"lint-staged": "^10.1.3",
|
||||
"lodash.startcase": "^4.4.0",
|
||||
"prettier": "2.2.1",
|
||||
"prettier-plugin-solidity": "^1.0.0-beta.10",
|
||||
"prettier-plugin-solidity": "1.0.0-beta.10",
|
||||
"pretty-quick": "^2.0.1",
|
||||
"secp256k1": "^3.7.1",
|
||||
"solc-0.8": "npm:solc@^0.8.4",
|
||||
"truffle": "^5.2.3",
|
||||
"web3": "^1.3.5"
|
||||
"typescript": "^4.3.5",
|
||||
"web3": "^1.5.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"sse4_crc32": "npm:@node-rs/crc32@1.0.0"
|
||||
@@ -70,7 +71,9 @@
|
||||
"lint-staged": {
|
||||
"*.{js,ts,tsx}": "eslint --cache --fix"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/**"
|
||||
]
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"packages/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,8 @@ export const Balances = () => {
|
||||
let total = 0n;
|
||||
const store = new Map<Id, string>();
|
||||
function getOrCreate(address: string) {
|
||||
if (store.has(address)) return store.get(address);
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
if (store.has(address)) return store.get(address)!; // Null assertion because we know the map element exists.
|
||||
return create(address);
|
||||
}
|
||||
function create(addr: string) {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"@uniswap/v3-core": "1.0.0-rc.2",
|
||||
"@uniswap/v3-periphery": "1.0.0-beta.23",
|
||||
"cli-progress": "^3.8.2",
|
||||
"ethers": "^5.0.17",
|
||||
"ethers": "^5.4.2",
|
||||
"googleapis": "39",
|
||||
"highland": "^2.13.5",
|
||||
"lodash": "^4.17.20",
|
||||
@@ -21,7 +21,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^8.2.0",
|
||||
"tape": "^5.0.1"
|
||||
"tape": "^5.0.1",
|
||||
"@openzeppelin/contracts": "4.1.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.com/",
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
"@types/url-join": "^4.0.0",
|
||||
"@typescript-eslint/parser": "^4.24.0",
|
||||
"ts-mocha": "^8.0.0",
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.1.3"
|
||||
"ts-node": "^10.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/express": "^4.17.11",
|
||||
@@ -22,7 +21,7 @@
|
||||
"@uma/sdk": "^0.4.1",
|
||||
"body-parser": "^1.19.0",
|
||||
"cors": "^2.8.5",
|
||||
"ethers": "^5.1.3",
|
||||
"ethers": "^5.4.2",
|
||||
"express": "^4.17.1",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
|
||||
@@ -5,7 +5,7 @@ import { utils, BigNumber, Contract } from "ethers";
|
||||
import assert from "assert";
|
||||
const { parseUnits, parseBytes32String } = utils;
|
||||
|
||||
export const SCALING_MULTIPLIER = parseUnits("1");
|
||||
export const SCALING_MULTIPLIER: BigNumber = parseUnits("1");
|
||||
export type BigNumberish = number | string | BigNumber;
|
||||
|
||||
export { parseUnits };
|
||||
@@ -28,7 +28,7 @@ export function calcGcr(
|
||||
uma.tables.emps.Data,
|
||||
"totalTokensOutstanding" | "totalPositionCollateral" | "tokenDecimals" | "collateralDecimals"
|
||||
>
|
||||
) {
|
||||
): BigNumber {
|
||||
const { totalTokensOutstanding, totalPositionCollateral, tokenDecimals, collateralDecimals } = params;
|
||||
assert(uma.utils.exists(totalTokensOutstanding), "requires total tokens outstanding");
|
||||
assert(uma.utils.exists(totalPositionCollateral), "requires total position collateral");
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
"commander": "^7.2.0",
|
||||
"lodash": "^4.17.21",
|
||||
"node-fetch": "^2.6.1",
|
||||
"typescript": "^4.2.2",
|
||||
"winston-transport": "^4.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -22,7 +21,8 @@
|
||||
"@types/cli-progress": "^3.9.1",
|
||||
"@types/commander": "^2.12.2",
|
||||
"@types/mocha": "^8.2.2",
|
||||
"@types/node-fetch": "^2.5.8"
|
||||
"@types/node-fetch": "^2.5.8",
|
||||
"web3": "^1.5.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.com/",
|
||||
|
||||
@@ -3,6 +3,7 @@ import Web3 from "web3";
|
||||
const { isAddress } = Web3.utils;
|
||||
|
||||
import { strategyRunnerConfig, buildBotConfigs, buildGlobalWhitelist } from "../src/ConfigBuilder";
|
||||
import { getWeb3 } from "@uma/common";
|
||||
|
||||
// simple config with a permalink to a white lists.
|
||||
const minimalConfig: strategyRunnerConfig = {
|
||||
@@ -35,6 +36,11 @@ const minimumRequiredConfigKeys = [
|
||||
"pollingDelay",
|
||||
];
|
||||
describe("buildGlobalWhitelist", async function () {
|
||||
before(async () => {
|
||||
// Web3 instance (for some reason) needs to be warmed up.
|
||||
const web3 = getWeb3(minimalConfig.botNetwork);
|
||||
await web3.eth.getAccounts();
|
||||
});
|
||||
it("Correctly fetches global whitelist", async function (this: any) {
|
||||
this.timeout(60000);
|
||||
// Construct a whitelist from all current EMPs on the affiliates payout. Append a sample address to the list.
|
||||
|
||||
@@ -45,13 +45,15 @@
|
||||
"hardhat": "^2.5.0",
|
||||
"hardhat-deploy": "^0.8.11",
|
||||
"hardhat-gas-reporter": "^1.0.4",
|
||||
"hardhat-typechain": "^0.3.5",
|
||||
"lodash.uniqby": "^4.7.0",
|
||||
"minimist": "^1.2.0",
|
||||
"moment": "^2.24.0",
|
||||
"node-metamask": "github:UMAprotocol/node-metamask",
|
||||
"require-context": "^1.1.0",
|
||||
"solidity-coverage": "^0.7.13",
|
||||
"truffle-deploy-registry": "^0.5.1",
|
||||
"web3": "^1.3.5"
|
||||
"web3": "^1.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eth-optimism/hardhat-ovm": "^0.2.2",
|
||||
@@ -62,7 +64,6 @@
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@types/ethereum-protocol": "^1.0.0",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"ethers": "^5.4.1",
|
||||
"typescript": "^4.1.3"
|
||||
"ethers": "^5.4.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { getNodeUrl, mnemonic } = require("./TruffleConfig");
|
||||
const path = require("path");
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function getHardhatConfig(configOverrides, workingDir = "./", includeTruffle = true) {
|
||||
// Hardhat plugins. These are imported inside `getHardhatConfig` so that other packages importing this function
|
||||
// get access to the plugins as well.
|
||||
@@ -88,16 +88,6 @@ function getHardhatConfig(configOverrides, workingDir = "./", includeTruffle = t
|
||||
apiKey: process.env.ETHERSCAN_API_KEY,
|
||||
},
|
||||
namedAccounts: { deployer: 0 },
|
||||
external: {
|
||||
deployments: {
|
||||
mainnet: [path.join(workingDir, "build/contracts"), path.join(workingDir, "deployments/mainnet")],
|
||||
mumbai: [path.join(workingDir, "build/contracts"), path.join(workingDir, "deployments/mumbai")],
|
||||
matic: [path.join(workingDir, "build/contracts"), path.join(workingDir, "deployments/matic")],
|
||||
rinkeby: [path.join(workingDir, "build/contracts"), path.join(workingDir, "deployments/rinkeby")],
|
||||
kovan: [path.join(workingDir, "build/contracts"), path.join(workingDir, "deployments/kovan")],
|
||||
goerli: [path.join(workingDir, "build/contracts"), path.join(workingDir, "deployments/goerli")],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return { ...defaultConfig, ...configOverrides };
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const uniqBy = require("lodash.uniqby");
|
||||
|
||||
const { task, types } = require("hardhat/config");
|
||||
|
||||
function removeFileIfExists(filename) {
|
||||
try {
|
||||
fs.unlinkSync(filename);
|
||||
} catch (e) {
|
||||
// do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeClassName(name) {
|
||||
const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1); // Capitalize first letter.
|
||||
return capitalizedName.replace(/_/g, ""); // Remove underscores.
|
||||
}
|
||||
|
||||
async function getArtifactPathList(hre, relativeTo) {
|
||||
const artifactPaths = await hre.artifacts.getArtifactPaths();
|
||||
|
||||
// Generate a unique list of artifacts and paths to them. Unique is necessary because there are some redundantly
|
||||
// named contracts.
|
||||
return uniqBy(
|
||||
artifactPaths.map((artifactPath) => ({
|
||||
contractName: path.basename(artifactPath).split(".")[0],
|
||||
relativePath: `./${path.relative(path.dirname(relativeTo), artifactPath)}`,
|
||||
})),
|
||||
"contractName"
|
||||
);
|
||||
}
|
||||
|
||||
function getCorePath(hre, relativeTo) {
|
||||
const artifactPath = hre.config.paths.artifacts ? path.join(hre.config.paths.artifacts, "../") : "./";
|
||||
return `./${path.relative(relativeTo, artifactPath)}`;
|
||||
}
|
||||
|
||||
function getAddressesMap(hre) {
|
||||
// Generate a map of name => chain id => address.
|
||||
const networksPath = path.join(getCorePath(hre, "./"), "networks");
|
||||
const dirs = fs.readdirSync(networksPath);
|
||||
const addresses = {};
|
||||
for (const dir of dirs) {
|
||||
const chainId = parseInt(dir.split(".")[0]);
|
||||
const deployments = JSON.parse(fs.readFileSync(path.join(networksPath, dir), "utf8"));
|
||||
|
||||
// Loop over the deployments in the file and save each one.
|
||||
for (const { contractName, address, deploymentName } of deployments) {
|
||||
// If deploymentName isn't specified, use contractName.
|
||||
const name = deploymentName ? deploymentName : contractName;
|
||||
if (!addresses[name]) {
|
||||
addresses[name] = {};
|
||||
}
|
||||
addresses[name][chainId] = address;
|
||||
}
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
|
||||
task("generate-contracts-frontend", "Generate typescipt for the contracts-frontend package")
|
||||
.addParam("out", "browser ts output file", undefined, types.string)
|
||||
.setAction(async function (taskArguments, hre) {
|
||||
const { out } = taskArguments;
|
||||
removeFileIfExists(out);
|
||||
|
||||
const artifacts = await getArtifactPathList(hre, "./");
|
||||
const addresses = getAddressesMap(hre);
|
||||
|
||||
// Write Ethers contract types/factories export.
|
||||
fs.appendFileSync(
|
||||
out,
|
||||
`export type {
|
||||
TypedListener as TypedListenerEthers,
|
||||
MinEthersFactory as MinEthersFactoryEthers,
|
||||
GetContractTypeFromFactory as GetContractTypeFromFactoryEthers,
|
||||
GetARGsTypeFromFactory as GetARGsTypeFromFactoryEthers,
|
||||
TypedEventFilter as TypedEventFilterEthers,
|
||||
TypedEvent as TypedEventEthers,
|
||||
} from "../typechain/ethers/commons";\n`
|
||||
);
|
||||
|
||||
fs.appendFileSync(out, "export type {\n");
|
||||
artifacts.forEach(({ contractName }) => {
|
||||
if (fs.existsSync(`typechain/ethers/${contractName}.d.ts`))
|
||||
fs.appendFileSync(out, ` ${contractName} as ${contractName}Ethers,\n`);
|
||||
});
|
||||
fs.appendFileSync(out, '} from "../typechain/ethers";\n');
|
||||
|
||||
fs.appendFileSync(out, "export {\n");
|
||||
artifacts.forEach(({ contractName }) => {
|
||||
if (fs.existsSync(`typechain/ethers/factories/${contractName}__factory.ts`))
|
||||
fs.appendFileSync(out, ` ${contractName}__factory as ${contractName}Ethers__factory,\n`);
|
||||
});
|
||||
fs.appendFileSync(out, '} from "../typechain/ethers";\n');
|
||||
|
||||
// Write Web3 contract types.
|
||||
artifacts.forEach(({ contractName }) => {
|
||||
if (fs.existsSync(`typechain/web3/${contractName}.d.ts`))
|
||||
fs.appendFileSync(
|
||||
out,
|
||||
`export type { ${normalizeClassName(contractName)} as ${normalizeClassName(
|
||||
contractName
|
||||
)}Web3 } from "../typechain/web3/${contractName}";\n`
|
||||
);
|
||||
});
|
||||
|
||||
// Write abi and bytecode for the browser file.
|
||||
// Note: the idea behind writing the functions this way is to make them as optimized as possible for tree-shaking
|
||||
// to remove any unused json files. In modern versions of webpack, this should allow absolutely _no_ artifact
|
||||
// information that isn't needed to be pulled in.
|
||||
artifacts.forEach(({ contractName, relativePath }) => {
|
||||
const abi = JSON.stringify(JSON.parse(fs.readFileSync(relativePath)).abi);
|
||||
fs.appendFileSync(out, `export function get${contractName}Abi(): any[] { return JSON.parse(\`${abi}\`); }\n`);
|
||||
});
|
||||
artifacts.forEach(({ contractName, relativePath }) => {
|
||||
const bytecode = JSON.stringify(JSON.parse(fs.readFileSync(relativePath)).bytecode);
|
||||
fs.appendFileSync(out, `export function get${contractName}Bytecode(): string { return \`${bytecode}\`; }\n`);
|
||||
});
|
||||
|
||||
// Creates get[name]Address(chainId) for using switch statements.
|
||||
for (const [name, addressesByChain] of Object.entries(addresses)) {
|
||||
const declaration = `export function get${name}Address(chainId: number): string {\n switch (chainId.toString()) {\n`;
|
||||
const cases = Object.entries(addressesByChain).map(([chainId, address]) => {
|
||||
return ` case "${chainId}":\n return "${address}";\n`;
|
||||
});
|
||||
const endStatement = ` default:\n throw new Error(\`No address found for deployment ${name} on chainId \${chainId}\`)\n }\n}\n`;
|
||||
fs.appendFileSync(out, declaration.concat(...cases, endStatement));
|
||||
}
|
||||
});
|
||||
|
||||
task("generate-contracts-node", "Generate typescipt for the contracts-node package")
|
||||
.addParam("out", "node ts output file", undefined, types.string)
|
||||
.setAction(async function (taskArguments, hre) {
|
||||
const { out } = taskArguments;
|
||||
removeFileIfExists(out);
|
||||
|
||||
const artifacts = await getArtifactPathList(hre, out);
|
||||
const addresses = getAddressesMap(hre);
|
||||
|
||||
// Write Ethers contract types/factories export.
|
||||
fs.appendFileSync(
|
||||
out,
|
||||
`export type {
|
||||
TypedListener as TypedListenerEthers,
|
||||
MinEthersFactory as MinEthersFactoryEthers,
|
||||
GetContractTypeFromFactory as GetContractTypeFromFactoryEthers,
|
||||
GetARGsTypeFromFactory as GetARGsTypeFromFactoryEthers,
|
||||
TypedEventFilter as TypedEventFilterEthers,
|
||||
TypedEvent as TypedEventEthers,
|
||||
} from "../typechain/ethers/commons";\n`
|
||||
);
|
||||
|
||||
fs.appendFileSync(out, "export type {\n");
|
||||
artifacts.forEach(({ contractName }) => {
|
||||
if (fs.existsSync(`typechain/ethers/${contractName}.d.ts`))
|
||||
fs.appendFileSync(out, ` ${contractName} as ${contractName}Ethers,\n`);
|
||||
});
|
||||
fs.appendFileSync(out, '} from "../typechain/ethers";\n');
|
||||
|
||||
fs.appendFileSync(out, "export {\n");
|
||||
artifacts.forEach(({ contractName }) => {
|
||||
if (fs.existsSync(`typechain/ethers/factories/${contractName}__factory.ts`))
|
||||
fs.appendFileSync(out, ` ${contractName}__factory as ${contractName}Ethers__factory,\n`);
|
||||
});
|
||||
fs.appendFileSync(out, '} from "../typechain/ethers";\n');
|
||||
|
||||
// Write Web3 contract types.
|
||||
artifacts.forEach(({ contractName }) => {
|
||||
if (fs.existsSync(`typechain/web3/${contractName}.d.ts`))
|
||||
fs.appendFileSync(
|
||||
out,
|
||||
`export type { ${normalizeClassName(contractName)} as ${normalizeClassName(
|
||||
contractName
|
||||
)}Web3 } from "../typechain/web3/${contractName}";\n`
|
||||
);
|
||||
});
|
||||
|
||||
// Write abi and bytecode for the nodejs file.
|
||||
// Write an object that maps artifacts to their paths.
|
||||
fs.appendFileSync(out, "const artifactPaths = {\n");
|
||||
artifacts.forEach(({ contractName, relativePath }) =>
|
||||
fs.appendFileSync(out, ` ${contractName}: "${relativePath}",\n`)
|
||||
);
|
||||
fs.appendFileSync(out, "};\n");
|
||||
fs.appendFileSync(out, "type ContractName = keyof typeof artifactPaths;\n");
|
||||
|
||||
// Use object to import the correct artifact for each contract name and return to the user.
|
||||
fs.appendFileSync(
|
||||
out,
|
||||
"export function getAbi(contractName: ContractName): any[] { return require(artifactPaths[contractName]).abi; }\n"
|
||||
);
|
||||
fs.appendFileSync(
|
||||
out,
|
||||
"export function getBytecode(contractName: ContractName): string { return require(artifactPaths[contractName]).bytecode; }\n"
|
||||
);
|
||||
|
||||
// Creates get[name]Address(chainId) using switch statements.
|
||||
// Note: don't export these functions as they are only used internally.
|
||||
for (const [name, addressesByChain] of Object.entries(addresses)) {
|
||||
const declaration = `function get${name}Address(chainId: number): string {\n switch (chainId.toString()) {\n`;
|
||||
const cases = Object.entries(addressesByChain).map(([chainId, address]) => {
|
||||
return ` case "${chainId}":\n return "${address}";\n`;
|
||||
});
|
||||
const endStatement = ` default:\n throw new Error(\`No address found for deployment ${name} on chainId \${chainId}\`)\n }\n}\n`;
|
||||
fs.appendFileSync(out, declaration.concat(...cases, endStatement));
|
||||
}
|
||||
|
||||
// Constructs a mapping of name to address function for nodejs.
|
||||
fs.appendFileSync(out, "const addressFunctions = {\n");
|
||||
Object.keys(addresses).forEach((name) => fs.appendFileSync(out, ` ${name}: get${name}Address,\n`));
|
||||
fs.appendFileSync(out, "};\n");
|
||||
fs.appendFileSync(out, "type DeploymentName = keyof typeof addressFunctions;\n");
|
||||
|
||||
// Creates a getAddress(name, chainId) function in nodejs that routes to the right get[name]Address function using
|
||||
// the above mapping.
|
||||
fs.appendFileSync(
|
||||
out,
|
||||
`function isDeploymentName(name: string): name is DeploymentName { return addressFunctions.hasOwnProperty(name); }
|
||||
interface HRE {
|
||||
getChainId: () => Promise<string>;
|
||||
deployments: {
|
||||
get: (name: string) => { address: string };
|
||||
getOrNull: (name: string) => ({ address: string } | null)
|
||||
}
|
||||
}
|
||||
export async function getAddress(name: DeploymentName | ContractName, chainId: number): Promise<string> {
|
||||
if (typeof chainId !== "number") throw new Error("chainId must be a number");
|
||||
const hre = (global as unknown as { hre?: HRE }).hre;
|
||||
const hreDeployment = hre && parseInt(await hre.getChainId()) === chainId && await hre.deployments.getOrNull(name);
|
||||
if (hreDeployment) return hreDeployment.address;
|
||||
if (!isDeploymentName(name)) throw new Error(\`No deployments for name: \${name}\`);
|
||||
const fn = addressFunctions[name];
|
||||
return fn(chainId);
|
||||
}
|
||||
`
|
||||
);
|
||||
});
|
||||
|
||||
task("load-addresses", "Load addresses from the networks folder into the hardhat deployments folder").setAction(
|
||||
async function (taskArguments, hre) {
|
||||
// Generate chain id mapping.
|
||||
const chainIdToNetworkName = {};
|
||||
for (const [name, { chainId }] of Object.entries(hre.config.networks)) {
|
||||
chainIdToNetworkName[chainId] = name;
|
||||
}
|
||||
|
||||
const dirs = fs.readdirSync("./networks");
|
||||
for (const dir of dirs) {
|
||||
// Infer chainId and network name from the file we're reading.
|
||||
const chainId = parseInt(dir.split(".")[0]);
|
||||
const networkName = chainIdToNetworkName[chainId];
|
||||
if (!networkName) {
|
||||
console.error(`Skipping file ./networks/${dir} because there is no configured network for this chainId`);
|
||||
}
|
||||
// Force hardhat deployment to read the intended network name.
|
||||
hre.network.name = networkName;
|
||||
const deployments = JSON.parse(fs.readFileSync(`./networks/${dir}`, "utf8"));
|
||||
|
||||
// Loop over the deployments in the file and save each one.
|
||||
for (const { contractName, address, deploymentName } of deployments) {
|
||||
// If deploymentName isn't specified, use contractName.
|
||||
const saveName = deploymentName ? deploymentName : contractName;
|
||||
const abi = hre.artifacts.readArtifactSync(contractName).abi;
|
||||
|
||||
// Save the deployment using hardhat deploy's built-in function.
|
||||
await hre.deployments.save(saveName, { address, abi });
|
||||
}
|
||||
|
||||
// Ensure the chainId file records the correct chainId.
|
||||
const chainIdFilePath = `./deployments/${networkName}/.chainId`;
|
||||
fs.unlinkSync(chainIdFilePath);
|
||||
fs.writeFileSync(chainIdFilePath, chainId.toString());
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,80 @@
|
||||
# @uma/contracts-frontend
|
||||
|
||||
This package exports all UMA smart contract artifacts specifically meant for consumption in a frontend. These exports
|
||||
are specifically optimized for frontends so they are able to drop any unused artifacts in order to keep the bundle size
|
||||
small.
|
||||
|
||||
## Installing the package
|
||||
|
||||
```bash
|
||||
yarn add @uma/contracts-frontend
|
||||
```
|
||||
|
||||
## Importing artifacts directly
|
||||
|
||||
To import artifacts directly into your tool of choice, the index file provides convenient functions for doing so:
|
||||
|
||||
```js
|
||||
import { getVotingAbi, getVotingBytecode, getVotingAddress } from "@uma/contracts-frontend"
|
||||
|
||||
// Gets the abi object for the Voting contract.
|
||||
// This will be needed to interact with the voting contract.
|
||||
const votingAbi = getAbiVotingAbi()
|
||||
|
||||
// Gets the bytecode string for the voting contract.
|
||||
// This should usually only be required if you need to deploy a voting contract (rare).
|
||||
const votingBytecode = getVotingBytecode()
|
||||
|
||||
// Gets the address of the voting contract for chain id 1 (eth mainnet).
|
||||
// If there is no single canonical deployment of a particular contract on the network provided, this will fail.
|
||||
const chainId = 1
|
||||
const votingAddress = getVotingAddress(chainId)
|
||||
```
|
||||
|
||||
## Typescript!
|
||||
|
||||
Typescript is fully supported for all of the above operations:
|
||||
|
||||
```ts
|
||||
import { getVotingAbi, getVotingBytecode, getVotingAddress } from "@uma/contracts-frontend";
|
||||
...
|
||||
```
|
||||
|
||||
In addition to artifact support, typescript types (and sometimes factories) are available for ethers and web3.
|
||||
|
||||
### Ethers
|
||||
|
||||
The best support is for Ethers contract types. To construct an Ethers contract, import one of the ethers factories:
|
||||
|
||||
```ts
|
||||
import { VotingEthers__factory, getVotingAddress } from "@uma/contracts-frontend" // Factory to create ethers instance.
|
||||
import type { VotingEthers } from "@uma/contracts-frontend" // Type for ethers instance.
|
||||
|
||||
const NETWORK_ID = 1
|
||||
const VOTING_ADDRESS = getVotingAddress(NETWORK_ID)
|
||||
|
||||
// Note: the explicit type here isn't necessary -- this is just provided to document what VotingEthers is.
|
||||
const votingInstance: VotingEthers = VotingEthers__factory.connect(VOTING_ADDRESS, providerOrSigner)
|
||||
```
|
||||
|
||||
### Web3
|
||||
|
||||
Web3 factories are not provided, but web3 contract types are. They can be used as follows:
|
||||
|
||||
```ts
|
||||
import type { VotingWeb3 } from "@uma/contracts-frontend"
|
||||
import { getVotingAbi, getVotingAddress, getVotingBytecode } from "@uma/contracts-frontend"
|
||||
|
||||
const VOTING_ABI = getVotingAbi()
|
||||
const NETWORK_ID = 1
|
||||
const VOTING_ADDRESS = getVotingAddress(NETWORK_ID)
|
||||
|
||||
// Create a voting instance to represent a pre-deployed voting contract.
|
||||
const voting = new web3.eth.Contract(VOTING_ABI, VOTING_ADDRESS) as VotingWeb3
|
||||
|
||||
// Or you can create a new voting instance using the bytecode.
|
||||
const VOTING_BYTECODE = getVotingBytecode()
|
||||
const newVotingInstance = (await new web3Instance.eth.Contract(VOTING_ABI, undefined)
|
||||
.deploy({ data: VOTING_BYTECODE, arguments: VOTING_ARGS })
|
||||
.send({ from: YOUR_ADDRESS })) as VotingWeb3
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
const { getHardhatConfig } = require("@uma/common");
|
||||
|
||||
const path = require("path");
|
||||
const coreWkdir = path.dirname(require.resolve("@uma/core/package.json"));
|
||||
const configOverride = {
|
||||
paths: {
|
||||
sources: `${coreWkdir}/contracts`,
|
||||
artifacts: `${coreWkdir}/artifacts`,
|
||||
cache: `${coreWkdir}/cache`,
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = getHardhatConfig(configOverride, __dirname, false);
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "@uma/contracts-frontend",
|
||||
"version": "0.1.0",
|
||||
"description": "UMA smart contracts and unit tests",
|
||||
"devDependencies": {
|
||||
"@ethersproject/abi": "^5.4.0",
|
||||
"@ethersproject/contracts": "^5.4.0",
|
||||
"@ethersproject/abstract-provider": "^5.4.0",
|
||||
"@ethersproject/providers": "^5.4.2",
|
||||
"@uma/core": "^2.5.0",
|
||||
"@uma/common": "^2.4.0",
|
||||
"ethers": "^5.4.2"
|
||||
},
|
||||
"homepage": "https://umaproject.org",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.com/",
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/UMAprotocol/protocol.git"
|
||||
},
|
||||
"files": [
|
||||
"dist/**/*"
|
||||
],
|
||||
"main": "dist/generated/index.js",
|
||||
"types": "dist/generated/index.d.ts",
|
||||
"module": "dist/generated/index.js",
|
||||
"side-effects": false,
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "echo 'No tests configured'",
|
||||
"clean": "rm -rf dist generated typechain",
|
||||
"generate-ts": "yarn clean && mkdir generated typechain && cp -R ../core/contract-types/* typechain/ && yarn hardhat generate-contracts-frontend --out ./generated/index.ts",
|
||||
"build": "yarn generate-ts && yarn tsc && rsync -R ./typechain/**/*.d.ts ./dist",
|
||||
"prepublish": "yarn build"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/UMAprotocol/protocol/issues"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"include": ["generated/index.ts"],
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"declaration": true,
|
||||
"resolveJsonModule": true,
|
||||
"target": "ES2020",
|
||||
"module": "ES2020",
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
# @uma/contracts-node
|
||||
|
||||
This package exports all UMA smart contract artifacts specifically meant for consumption in nodejs.
|
||||
|
||||
## Installing the package
|
||||
|
||||
```bash
|
||||
yarn add @uma/contracts-node
|
||||
```
|
||||
|
||||
## Importing artifacts directly
|
||||
|
||||
To import artifacts directly into your tool of choice, the index file provides convenient functions for doing so:
|
||||
|
||||
```js
|
||||
const { getAbi, getBytecode, getAddress } = require("@uma/contracts-node")
|
||||
|
||||
// Gets the abi object for the Voting contract.
|
||||
// This will be needed to interact with the voting contract.
|
||||
const votingAbi = getAbi("Voting")
|
||||
|
||||
// Gets the bytecode string for the voting contract.
|
||||
// This should usually only be required if you need to deploy a voting contract (rare).
|
||||
const votingBytecode = getBytecode("Voting")
|
||||
|
||||
// Gets the address of the voting contract for chain id 1 (eth mainnet).
|
||||
// If there is no single canonical deployment of a particular contract on the network provided, this will fail.
|
||||
const chainId = 1
|
||||
const votingAddress = getAddress("Voting", chainId)
|
||||
```
|
||||
|
||||
## Typescript!
|
||||
|
||||
Typescript is fully supported for all of the above operations:
|
||||
|
||||
```ts
|
||||
import { getAbi, getBytecode, getAddress } from "@uma/contracts-node";
|
||||
...
|
||||
```
|
||||
|
||||
In addition to artifact support, typescript types (and sometimes factories) are available for ethers and web3.
|
||||
|
||||
### Ethers
|
||||
|
||||
The best support is for Ethers contract types. To construct an Ethers contract, import one of the ethers factories:
|
||||
|
||||
```ts
|
||||
import { VotingEthers__factory, getAddress } from "@uma/contracts-node" // Factory to create ethers instance.
|
||||
import type { VotingEthers } from "@uma/contracts-node" // Type for ethers instance.
|
||||
|
||||
const NETWORK_ID = 1
|
||||
const VOTING_ADDRESS = getAddress("Voting", NETWORK_ID)
|
||||
|
||||
// Note: the explicit type here isn't necessary -- this is just provided to document what VotingEthers is.
|
||||
const votingInstance: VotingEthers = VotingEthers__factory.connect(VOTING_ADDRESS, providerOrSigner)
|
||||
```
|
||||
|
||||
### Web3
|
||||
|
||||
Web3 factories are not provided, but web3 contract types are. They can be used as follows:
|
||||
|
||||
```ts
|
||||
import type { VotingWeb3 } from "@uma/contracts-node"
|
||||
import { getAbi, getAddress, getBytecode } from "@uma/contracts-node"
|
||||
|
||||
const VOTING_ABI = getAbi("Voting")
|
||||
const NETWORK_ID = 1
|
||||
const VOTING_ADDRESS = getAddress("Voting", NETWORK_ID)
|
||||
|
||||
// Create a voting instance to represent a pre-deployed voting contract.
|
||||
const voting = new web3.eth.Contract(VOTING_ABI, VOTING_ADDRESS) as VotingWeb3
|
||||
|
||||
// Or you can create a new voting instance using the bytecode.
|
||||
const VOTING_BYTECODE = getBytecode("Voting")
|
||||
const newVotingInstance = (await new web3Instance.eth.Contract(VOTING_ABI, undefined)
|
||||
.deploy({ data: VOTING_BYTECODE, arguments: VOTING_ARGS })
|
||||
.send({ from: YOUR_ADDRESS })) as VotingWeb3
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
This package works well with hardhat test. If you use hardhat-deploy to set up deployments in hardhat, `getAddress`
|
||||
should recognize them.
|
||||
|
||||
```js
|
||||
// Note: if running directly from node rather than inside hardhat, you will need to manually set global.hre.
|
||||
// @uma/contracts-node uses the global object to detect hardhat. For hardhat tests, this step should be
|
||||
// unnecessary.
|
||||
global.hre = require("hardhat");
|
||||
const { getAddress } = require("@uma/contracts-node");
|
||||
|
||||
...
|
||||
// hre.deployments.deploy deploys and saves the deployment.
|
||||
await hre.deployments.deploy("Voting", { args: YOUR_ARGS, from: YOUR_ADDRESS });
|
||||
|
||||
// To add an address deployed without .deploy
|
||||
// hre.deployments.save("Voting", { address: VOTING_ADDRESS, abi: VOTING_ABI });
|
||||
|
||||
// Address should be pulled out as expected.
|
||||
const address = getAddress("Voting", parseInt(await hre.getChainId()));
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
const { getHardhatConfig } = require("@uma/common");
|
||||
|
||||
const path = require("path");
|
||||
const coreWkdir = path.dirname(require.resolve("@uma/core/package.json"));
|
||||
const configOverride = {
|
||||
paths: { sources: `${coreWkdir}/contracts`, artifacts: `${coreWkdir}/artifacts`, cache: `${coreWkdir}/cache` },
|
||||
};
|
||||
|
||||
module.exports = getHardhatConfig(configOverride, __dirname, false);
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "@uma/contracts-node",
|
||||
"version": "0.1.0",
|
||||
"description": "UMA smart contracts and unit tests",
|
||||
"devDependencies": {
|
||||
"@ethersproject/abi": "^5.4.0",
|
||||
"@ethersproject/contracts": "^5.4.0",
|
||||
"@ethersproject/abstract-provider": "^5.4.0",
|
||||
"@ethersproject/providers": "^5.4.2",
|
||||
"@uma/core": "^2.5.0",
|
||||
"@uma/common": "^2.4.0",
|
||||
"ethers": "^5.4.2"
|
||||
},
|
||||
"homepage": "https://umaproject.org",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.com/",
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/UMAprotocol/protocol.git"
|
||||
},
|
||||
"files": [
|
||||
"dist/**/*"
|
||||
],
|
||||
"main": "dist/contracts-node/generated/index.js",
|
||||
"module": "dist/contracts-node/generated/index.js",
|
||||
"types": "dist/contracts-node/generated/index.d.ts",
|
||||
"sideEffects": false,
|
||||
"side-effects": false,
|
||||
"scripts": {
|
||||
"test": "echo 'No tests configured'",
|
||||
"clean": "rm -rf dist generated typechain",
|
||||
"generate-ts": "yarn clean && mkdir generated typechain && cp -R ../core/contract-types/* typechain/ && yarn hardhat generate-contracts-node --out ./generated/index.ts",
|
||||
"build": "yarn generate-ts && yarn tsc && rsync -R ./typechain/**/*.d.ts ./dist/contracts-node",
|
||||
"prepublish": "yarn build"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/UMAprotocol/protocol/issues"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"extends": "@tsconfig/node14/tsconfig.json",
|
||||
"esModuleInterop": true,
|
||||
"include": ["generated/index.ts", "../core/artifacts/**/*.json"],
|
||||
"exclude": ["../core/artifacts/build-info/**/*.json", "../core/artifacts/**/*.dbg.json"],
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"declaration": true,
|
||||
"resolveJsonModule": true,
|
||||
"target": "ES2020",
|
||||
"module": "CommonJS"
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,18 @@ const { getHardhatConfig } = require("@uma/common");
|
||||
const path = require("path");
|
||||
const coreWkdir = path.dirname(require.resolve("@uma/core/package.json"));
|
||||
const packageWkdir = path.dirname(require.resolve("@uma/core/package.json"));
|
||||
|
||||
let typechain = undefined;
|
||||
if (process.env.TYPECHAIN === "web3") {
|
||||
typechain = { outDir: "contract-types/web3", target: "web3-v1", alwaysGenerateOverloads: false };
|
||||
} else if (process.env.TYPECHAIN === "truffle") {
|
||||
typechain = { outDir: "contract-types/truffle", target: "truffle-v5", alwaysGenerateOverloads: false };
|
||||
} else if (process.env.TYPECHAIN === "ethers") {
|
||||
typechain = { outDir: "contract-types/ethers", target: "ethers-v5", alwaysGenerateOverloads: false };
|
||||
}
|
||||
|
||||
if (typechain !== undefined) require("@typechain/hardhat");
|
||||
|
||||
const configOverride = {
|
||||
paths: {
|
||||
root: coreWkdir,
|
||||
@@ -11,6 +23,7 @@ const configOverride = {
|
||||
cache: `${coreWkdir}/cache`,
|
||||
tests: `${packageWkdir}/test`,
|
||||
},
|
||||
typechain,
|
||||
};
|
||||
|
||||
module.exports = getHardhatConfig(configOverride, __dirname, false);
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"0x0246FBF444cAe32867b410464664f8F02e1822C7": [],
|
||||
"0xB3De1e212B49e68f4a68b5993f31f63946FCA2a6": [
|
||||
"0x40f941E48A552bF496B154Af6bf55725f18D77c3",
|
||||
"0x7c96d6235CfaaCcAc5d80fCe74E6032B25dd1F03",
|
||||
"0x0000000000000000000000000000000000000000"
|
||||
]
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"0xeF9c374b7976941fCAf5e501eaB531E430463fC6": [],
|
||||
"0x10E241725178991417E65fadE965Ca1F07852283": [
|
||||
"600",
|
||||
["50000000000000000"],
|
||||
["500000000000000"],
|
||||
1209600,
|
||||
"0x489Bf230d4Ab5c2083556E394a28276C22c3B580",
|
||||
"0xeD0169a88d267063184b0853BaAAAe66c3c154B2",
|
||||
"0x0000000000000000000000000000000000000000"
|
||||
],
|
||||
"0xbeCA65040Cc8497ABA9de30F0E413871282CFfC2": [],
|
||||
"0x7E617335cbe37110691bE81b5B498B7Fa81FB7B2": [],
|
||||
"0x1082C1878FAeAC03310468A379cf4D159939FA42": [
|
||||
"0xeD0169a88d267063184b0853BaAAAe66c3c154B2",
|
||||
"0xe7e87f89e3D15617261Fd52188Ca64803165f8Af",
|
||||
"0x0000000000000000000000000000000000000000"
|
||||
]
|
||||
}
|
||||
+20
-14
@@ -5,6 +5,7 @@
|
||||
"dependencies": {
|
||||
"@eth-optimism/contracts": "^0.4.5",
|
||||
"@eth-optimism/watcher": "^0.0.1-alpha.9",
|
||||
"@openzeppelin/contracts": "4.1.0",
|
||||
"@truffle/contract": "^4.3.15",
|
||||
"@uma/common": "^2.6.0",
|
||||
"@uma/core-1-1-0": "npm:@uma/core@1.1.0",
|
||||
@@ -21,17 +22,21 @@
|
||||
"decimal.js": "^10.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eth-optimism/smock": "^1.1.9",
|
||||
"@awaitjs/express": "^0.3.0",
|
||||
"@ethersproject/units": "^5.4.0",
|
||||
"@ethersproject/abi": "^5.4.0",
|
||||
"@ethersproject/contracts": "^5.4.0",
|
||||
"@ethersproject/abstract-provider": "^5.4.0",
|
||||
"@ethersproject/providers": "^5.4.2",
|
||||
"@eth-optimism/smock": "^1.1.9",
|
||||
"@ethersproject/units": "^5.0.3",
|
||||
"@google-cloud/bigquery": "^5.3.0",
|
||||
"@nomiclabs/ethereumjs-vm": "^4.2.2",
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||
"@openzeppelin/contracts": "4.1.0",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@typechain/ethers-v5": "^6.0.5",
|
||||
"@typechain/truffle-v5": "^4.0.1",
|
||||
"@typechain/web3-v1": "^2.2.0",
|
||||
"@typechain/ethers-v5": "^7.0.1",
|
||||
"@typechain/hardhat": "^2.2.0",
|
||||
"@typechain/truffle-v5": "^5.0.0",
|
||||
"@typechain/web3-v1": "^3.0.0",
|
||||
"@uma/financial-templates-lib": "^2.6.1",
|
||||
"@uma/merkle-distributor": "^1.2.4",
|
||||
"bignumber.js": "^8.0.1",
|
||||
@@ -39,7 +44,7 @@
|
||||
"chai": "^4.2.0",
|
||||
"coveralls": "^3.1.0",
|
||||
"ethereumjs-wallet": "^1.0.0",
|
||||
"ethers": "^5.1.3",
|
||||
"ethers": "^5.4.2",
|
||||
"express": "^4.17.1",
|
||||
"lodash": "^4.17.20",
|
||||
"minimist": "^1.2.0",
|
||||
@@ -49,8 +54,7 @@
|
||||
"solidity-coverage": "^0.7.2",
|
||||
"truffle-assertions": "^0.9.2",
|
||||
"truffle-deploy-registry": "^0.5.1",
|
||||
"typechain": "^4.0.3",
|
||||
"typescript": "^4.1.3",
|
||||
"typechain": "^5.1.2",
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"homepage": "https://umaproject.org",
|
||||
@@ -74,17 +78,19 @@
|
||||
"/dist/**/*",
|
||||
"/types/**/*"
|
||||
],
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"test": "yarn mocha-test && yarn hardhat-test",
|
||||
"truffle-test": "truffle test ./truffle-test/scripts/*",
|
||||
"hardhat-test": "hardhat test --network hardhat",
|
||||
"mocha-test": "mocha ./mocha-test --recursive",
|
||||
"load-addresses": "yarn run apply-registry",
|
||||
"clean": "rm -rf build",
|
||||
"build": "yarn truffle compile && yarn load-addresses && yarn generate-contract-types && yarn compile-ts && yarn buildLatestHardhatVersionHashes && yarn hardhat compile --network optimism",
|
||||
"load-addresses": "yarn run apply-registry && yarn hardhat load-addresses",
|
||||
"clean": "rm -rf build && rm -rf contract-types && rm -rf artifacts && rm -rf deployments && rm -rf dist",
|
||||
"build-contracts": "yarn truffle compile && yarn hardhat compile && yarn hardhat compile --network optimism",
|
||||
"build": "yarn build-contracts && yarn load-addresses && yarn generate-contract-types && yarn compile-ts && yarn buildLatestHardhatVersionHashes",
|
||||
"buildLatestHardhatVersionHashes": "yarn hardhat run ./scripts/BuildContractVersionHashes.js",
|
||||
"compile-ts": "rm -rf types dist && mkdir -p types/contract-types && rsync -R contract-types/**/*.d.ts ./types && tsc",
|
||||
"generate-contract-types": "rm -rf contract-types && typechain --target=web3-v1 './build/contracts/*.json' --outDir contract-types/web3 && typechain --target=truffle-v5 './build/contracts/*.json' --outDir contract-types/truffle && typechain --target=ethers-v5 './build/contracts/*.json' --outDir contract-types/ethers",
|
||||
"compile-ts": "rm -rf types dist && mkdir -p types/contract-types && rsync -R contract-types/**/*.d.ts ./types && tsc",
|
||||
"generate-contract-types": "rm -rf contract-types && TYPECHAIN=web3 yarn hardhat typechain && TYPECHAIN=truffle yarn hardhat typechain && TYPECHAIN=ethers yarn hardhat typechain",
|
||||
"prepublish": "yarn build"
|
||||
},
|
||||
"bugs": {
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
"moment-timezone": "^0.5.33",
|
||||
"node-fetch": "^2.6.0",
|
||||
"node-pagerduty": "^1.2.0",
|
||||
"web3": "^1.3.5",
|
||||
"web3": "^1.5.0",
|
||||
"winston": "^3.2.1",
|
||||
"winston-transport": "^4.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@openzeppelin/contracts": "4.1.0",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"bignumber.js": "^9.0.1",
|
||||
"typescript": "^4.1.3"
|
||||
"bignumber.js": "^9.0.1"
|
||||
},
|
||||
"homepage": "https://umaproject.org",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
|
||||
@@ -6,11 +6,10 @@
|
||||
"@uma/core": "^2.7.0",
|
||||
"chai": "^4.3.0",
|
||||
"commander": "^7.1.0",
|
||||
"ethers": "^5.0.31",
|
||||
"ethers": "^5.4.2",
|
||||
"ipfs-http-client": "^49.0.2",
|
||||
"mocha": "^8.3.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"typescript": "^4.2.2"
|
||||
"node-fetch": "^2.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/commander": "^2.12.2",
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"hardhat": "^2.4.3",
|
||||
"minimist": "^1.2.0",
|
||||
"winston": "^3.2.1",
|
||||
"web3": "^1.3.5"
|
||||
"web3": "^1.5.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"homepage": "https://umaproject.org",
|
||||
|
||||
@@ -38,9 +38,13 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@uma/core": "^2.7.0",
|
||||
"ethers": "^5.1.3"
|
||||
"ethers": "^5.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ethersproject/abi": "^5.4.0",
|
||||
"@ethersproject/contracts": "^5.4.0",
|
||||
"@ethersproject/abstract-provider": "^5.4.0",
|
||||
"@ethersproject/providers": "^5.4.2",
|
||||
"@size-limit/preset-small-lib": "^4.10.2",
|
||||
"size-limit": "^4.10.2",
|
||||
"tsdx": "^0.14.1",
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
"description": "Serverless orchestration scripts to run a parallel instances of scripts or bots",
|
||||
"dependencies": {
|
||||
"@truffle/contract": "^4.2.20",
|
||||
"@openzeppelin/contracts": "4.1.0",
|
||||
"@uma/common": "^2.6.0",
|
||||
"@uma/financial-templates-lib": "^2.6.1",
|
||||
"web3": "^1.3.5"
|
||||
"web3": "^1.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@awaitjs/express": "^0.3.0",
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
"@types/mocha": "^8.2.0",
|
||||
"@types/node": "^14.14.25",
|
||||
"chai": "^4.3.0",
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.1.3"
|
||||
"ts-node": "^10.1.0",
|
||||
"@uniswap/v3-periphery": "^1.0.0-beta.23"
|
||||
},
|
||||
"homepage": "https://umaproject.org",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
|
||||
Reference in New Issue
Block a user