Skip to content

Instantly share code, notes, and snippets.

@kendricktan
Created April 26, 2020 02:55
Show Gist options
  • Save kendricktan/b0999fb8f9fd5a1840cdcf1404c5efd9 to your computer and use it in GitHub Desktop.
Save kendricktan/b0999fb8f9fd5a1840cdcf1404c5efd9 to your computer and use it in GitHub Desktop.
UMA Deploy with Ethers
const { ethers } = require("ethers");
const { legos } = require("@studydefi/money-legos");
const { BigNumber } = require("ethers/utils/bignumber");
const { RegistryRolesEnum } = require("../../common/Enums.js");
const { interfaceName } = require("../utils/Constants.js");
const HDWalletProvider = require("@truffle/hdwallet-provider");
const provider = new ethers.providers.JsonRpcProvider();
const hdwallet = new HDWalletProvider(
"myth like bonus scare over problem client lizard pioneer submit female collect",
"http://localhost",
0,
10
);
const wallets = Object.keys(hdwallet.wallets).map(pk => new ethers.Wallet(hdwallet.wallets[pk]._privKey, provider));
const contractCreator = wallets[0];
const liquidator = wallets[1];
const disputer = wallets[2];
const sponsors = wallets.slice(3, 6); // accounts 3 -> 5
const tokenHolders = wallets.slice(7, 10); // accounts 6 -> 9
const sponsor1 = sponsors[0];
const addresses = {
Finder: "0x40f941E48A552bF496B154Af6bf55725f18D77c3",
VotingToken: "0x04Fa0d235C4abf4BcF4787aF4CF447DE572eF828",
Voting: "0xFe3C4F1ec9f5df918D42Ef7Ed3fBA81CC0086c5F",
Registry: "0x07D6A3b7a345576a22B63470c1cBdf133179257C",
FinancialContractsAdmin: "0x5dee86B9345A2b4631d087faC91e1609A1c9d9D7",
Store: "0xCEAEFC381e3268BA7F1ec92A7Ad637857ee56210",
Governor: "0x4Ca5348aA2fF1e9e854F3a22dc51AA2c70151408",
DesignatedVotingFactory: "0xE81EeE5Da165fA6863bBc82dF66E62d18625d592",
WETH9: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
Timer: "0x0000000000000000000000000000000000000000"
};
const jsonToContractFactory = jsonLoc => {
const def = require(jsonLoc);
return new ethers.ContractFactory(def.abi, def.bytecode, contractCreator);
};
const toBN = x => new BigNumber(x);
const toWei = x => ethers.utils.parseEther(x);
// Other UMA related contracts and mocks
const ExpiringMultiPartyCreator = jsonToContractFactory("../build/contracts/ExpiringMultiPartyCreator.json");
const Token = jsonToContractFactory("../build/contracts/ExpandedERC20.json");
const Finder = jsonToContractFactory("../build/contracts/Finder.json");
const Registry = jsonToContractFactory("../build/contracts/Registry.json");
const TokenFactory = jsonToContractFactory("../build/contracts/TokenFactory.json");
const ExpiringMultiParty = jsonToContractFactory("../build/contracts/ExpiringMultiParty.json");
const IdentifierWhitelist = jsonToContractFactory("../build/contracts/IdentifierWhitelist.json");
const AddressWhitelist = jsonToContractFactory("../build/contracts/AddressWhitelist.json");
const MockOracle = jsonToContractFactory("../build/contracts/MockOracle.json");
const Store = jsonToContractFactory("../build/contracts/Store.json");
const Timer = jsonToContractFactory("../build/contracts/Timer.json");
const main = async () => {
const mintAndApprove = toWei("100000000000000");
const timeOffsetBetweenTests = toBN(60 * 60);
// Deploy
// Ref to DAI Contract
const collateralToken = new ethers.Contract(legos.erc20.dai.address, legos.erc20.dai.abi, contractCreator);
// DAI Contract
const registry = await Registry.deploy({ gasLimit: 4000000 });
// TODO Use mainnet finder/oracle?
const timer = await Timer.deploy();
const store = await Store.deploy(timer.address);
const finder = await Finder.deploy();
const mockOracle = await MockOracle.deploy(finder.address, timer.address);
// Deploy contracts
const tokenFactory = await TokenFactory.deploy({ gasLimit: 4000000 });
const collateralCurrencyWhitelist = await AddressWhitelist.deploy({ gasLimit: 4000000 });
const expiringMultiPartyCreator = await ExpiringMultiPartyCreator.deploy(
addresses.Finder,
collateralCurrencyWhitelist.address,
tokenFactory.address,
timer.address,
{ gasLimit: 6000000 }
);
const startingTime = await expiringMultiPartyCreator.getCurrentTime();
const expirationTime = startingTime.add(toBN(60 * 60 * 24 * 30 * 3)); // Three month in the future
// Can't fork off Mainnet
// As it seems like Finder has some inconsistencies with the UMA-SDK
// i.e. bytes32(IdentifierWhitelist) does not exist in mainnet Finder
// https://etherscan.io/address/0x40f941E48A552bF496B154Af6bf55725f18D77c3
const constructorParams = {
expirationTimestamp: expirationTime.toString(),
withdrawalLiveness: "3600",
collateralAddress: collateralToken.address,
finderAddress: finder.address,
tokenFactoryAddress: tokenFactory.address,
timerAddress: timer.address,
priceFeedIdentifier: ethers.utils.formatBytes32String("UMATEST"),
syntheticName: "Test UMA Token",
syntheticSymbol: "UMATEST",
liquidationLiveness: "3600",
collateralRequirement: toWei("1.2"),
disputeBondPct: toWei("0.1"),
sponsorDisputeRewardPct: toWei("0.1"),
disputerDisputeRewardPct: toWei("0.1"),
minSponsorTokens: toWei("0")
};
// Add collateral to whitelist
await collateralCurrencyWhitelist.addToWhitelist(collateralToken.address);
// Add Registry
await registry
.connect(contractCreator)
.addMember(RegistryRolesEnum.CONTRACT_CREATOR, expiringMultiPartyCreator.address);
// Add oracle and identifier
const identifierWhitelist = await IdentifierWhitelist.deploy();
await identifierWhitelist.connect(contractCreator).addSupportedIdentifier(constructorParams.priceFeedIdentifier);
await finder
.connect(contractCreator)
.changeImplementationAddress(ethers.utils.formatBytes32String(interfaceName.Oracle), mockOracle.address);
await finder
.connect(contractCreator)
.changeImplementationAddress(
ethers.utils.formatBytes32String(interfaceName.IdentifierWhitelist),
identifierWhitelist.address
);
await finder
.connect(contractCreator)
.changeImplementationAddress(ethers.utils.formatBytes32String(interfaceName.Store), store.address);
const expiringMultiParty = await ExpiringMultiParty.deploy(
[
constructorParams.expirationTimestamp,
constructorParams.withdrawalLiveness,
constructorParams.collateralAddress,
constructorParams.finderAddress,
constructorParams.tokenFactoryAddress,
constructorParams.timerAddress,
constructorParams.priceFeedIdentifier,
constructorParams.syntheticName,
constructorParams.syntheticSymbol,
constructorParams.liquidationLiveness,
[constructorParams.collateralRequirement],
[constructorParams.disputeBondPct],
[constructorParams.sponsorDisputeRewardPct],
[constructorParams.disputerDisputeRewardPct],
[constructorParams.minSponsorTokens]
],
{ gasLimit: 6000000 }
);
const syntheticTokenAddress = await expiringMultiParty.tokenCurrency();
const syntheticToken = new ethers.Contract(syntheticTokenAddress, Token.interface.abi, sponsor1);
// Approve Token transfer
await collateralToken.connect(sponsor1).approve(expiringMultiParty.address, mintAndApprove);
await syntheticToken.connect(sponsor1).approve(expiringMultiParty.address, mintAndApprove);
// Mint some tokens
await expiringMultiParty.connect(sponsor1).create([toWei("150")], [toWei("100")], { gasLimit: 4000000 });
const syntheticBal = await syntheticToken.balanceOf(sponsor1.address);
console.log(`Sponsor 1 has: ${ethers.utils.parseEther(syntheticBal.toString())}`);
};
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment