Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script to deploy on Sepolia testnet #273

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions contracts/interfaces/external/IAggregatorInterface.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pragma solidity 0.6.10;

interface AggregatorInterface {
function latestAnswer() external view returns (int256);
function latestTimestamp() external view returns (uint256);
function latestRound() external view returns (uint256);
function getAnswer(uint256 roundId) external view returns (int256);
function getTimestamp(uint256 roundId) external view returns (uint256);

event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 timestamp);
event NewRound(uint256 indexed roundId, address indexed startedBy);
}
18 changes: 11 additions & 7 deletions contracts/protocol/PriceOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { IController } from "../interfaces/IController.sol";
import { IOracle } from "../interfaces/IOracle.sol";
import { IOracleAdapter } from "../interfaces/IOracleAdapter.sol";
import { PreciseUnitMath } from "../lib/PreciseUnitMath.sol";
import "hardhat/console.sol";


/**
Expand Down Expand Up @@ -115,24 +116,25 @@ contract PriceOracle is Ownable {
* @return Price of asset pair to 18 decimals of precision
*/
function getPrice(address _assetOne, address _assetTwo) external view returns (uint256) {
console.log("Price Oracle Test 1");
require(
controller.isSystemContract(msg.sender),
"PriceOracle.getPrice: Caller must be system contract."
);

console.log("Price Oracle Test 2");
bool priceFound;
uint256 price;

console.log("Price Oracle Test 2.5");
(priceFound, price) = _getDirectOrInversePrice(_assetOne, _assetTwo);

console.log("Price Oracle Test 3");
if (!priceFound) {
(priceFound, price) = _getPriceFromMasterQuote(_assetOne, _assetTwo);
}

console.log("Price Oracle Test 4");
if (!priceFound) {
(priceFound, price) = _getPriceFromAdapters(_assetOne, _assetTwo);
}

console.log("Price Oracle Test 5");
require(priceFound, "PriceOracle.getPrice: Price not found.");

return price;
Expand Down Expand Up @@ -259,13 +261,15 @@ contract PriceOracle is Ownable {
returns (bool, uint256)
{
IOracle directOracle = oracles[_assetOne][_assetTwo];
console.logAddress( address(directOracle));
bool hasDirectOracle = address(directOracle) != address(0);

console.log("Direct price 1");
// Check asset1 -> asset 2. If exists, then return value
if (hasDirectOracle) {
console.log("Direct price 2");
return (true, directOracle.read());
}

console.log("Direct price 3");
IOracle inverseOracle = oracles[_assetTwo][_assetOne];
bool hasInverseOracle = address(inverseOracle) != address(0);

Expand Down
3 changes: 2 additions & 1 deletion contracts/protocol/SetTokenCreator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
pragma solidity 0.6.10;
pragma experimental "ABIEncoderV2";

import "hardhat/console.sol";
import { IController } from "../interfaces/IController.sol";
import { SetToken } from "./SetToken.sol";
import { AddressArrayUtils } from "../lib/AddressArrayUtils.sol";
Expand Down Expand Up @@ -99,7 +100,7 @@ contract SetTokenCreator {
_name,
_symbol
);

console.log("Test: ", address(setToken));
// Registers Set with controller
controller.addSet(address(setToken));

Expand Down
9 changes: 6 additions & 3 deletions contracts/protocol/SetValuer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { IPriceOracle } from "../interfaces/IPriceOracle.sol";
import { PreciseUnitMath } from "../lib/PreciseUnitMath.sol";
import { Position } from "./lib/Position.sol";
import { ResourceIdentifier } from "./lib/ResourceIdentifier.sol";
import "hardhat/console.sol";


/**
Expand Down Expand Up @@ -81,16 +82,18 @@ contract SetValuer {
* @return SetToken valuation in terms of quote asset in precise units 1e18
*/
function calculateSetTokenValuation(ISetToken _setToken, address _quoteAsset) external view returns (uint256) {
console.log("Test");
IPriceOracle priceOracle = controller.getPriceOracle();
address masterQuoteAsset = priceOracle.masterQuoteAsset();
address[] memory components = _setToken.getComponents();
console.log("Test 1");
int256 valuation;

for (uint256 i = 0; i < components.length; i++) {
address component = components[i];
// Get component price from price oracle. If price does not exist, revert.
uint256 componentPrice = priceOracle.getPrice(component, masterQuoteAsset);

console.log(componentPrice);
int256 aggregateUnits = _setToken.getTotalComponentRealUnits(component);

// Normalize each position unit to preciseUnits 1e18 and cast to signed int
Expand All @@ -101,12 +104,12 @@ contract SetValuer {
// Calculate valuation of the component. Debt positions are effectively subtracted
valuation = normalizedUnits.preciseMul(componentPrice.toInt256()).add(valuation);
}

console.log("Test 2");
if (masterQuoteAsset != _quoteAsset) {
uint256 quoteToMaster = priceOracle.getPrice(_quoteAsset, masterQuoteAsset);
valuation = valuation.preciseDiv(quoteToMaster.toInt256());
}

console.log("Test 3");
return valuation.toUint256();
}
}
51 changes: 51 additions & 0 deletions contracts/protocol/integration/oracles/ChainlinkOracleAdapter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
pragma solidity 0.6.10;
import "../../../interfaces/external/IAggregatorInterface.sol";
import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
/**
* @title ChainlinkOracleAdapter
* @author Set Protocol
*
* Coerces outputs from Chainlink oracles to uint256 and adapts value to 18 decimals.
*/
contract ChainlinkOracleAdapter {
using SafeMath for uint256;

/* ============ Constants ============ */
uint256 public constant PRICE_MULTIPLIER = 1e10;

/* ============ State Variables ============ */
AggregatorInterface public oracle;

/* ============ Constructor ============ */
/*
* Set address of aggregator being adapted for use
*
* @param _oracle The address of medianizer being adapted from bytes to uint256
*/
constructor(
AggregatorInterface _oracle
)
public
{
oracle = _oracle;
}

/* ============ External ============ */

/*
* Reads value of oracle and coerces return to uint256 then applies price multiplier
*
* @returns Chainlink oracle price in uint256
*/
function read()
external
view
returns (uint256)
{
// Read value of medianizer and coerce to uint256
uint256 oracleOutput = uint256(oracle.latestAnswer());

// Apply multiplier to create 18 decimal price (since Chainlink returns 8 decimals)
return oracleOutput.mul(PRICE_MULTIPLIER);
}
}
3 changes: 0 additions & 3 deletions contracts/protocol/modules/v1/BasicIssuanceModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,10 @@ contract BasicIssuanceModule is ModuleBase, ReentrancyGuard {
require(_quantity > 0, "Issue quantity must be > 0");

address hookContract = _callPreIssueHooks(_setToken, _quantity, msg.sender, _to);

(
address[] memory components,
uint256[] memory componentQuantities
) = getRequiredComponentUnitsForIssue(_setToken, _quantity);

// For each position, transfer the required underlying to the SetToken
for (uint256 i = 0; i < components.length; i++) {
// Transfer the component to the SetToken
Expand All @@ -114,7 +112,6 @@ contract BasicIssuanceModule is ModuleBase, ReentrancyGuard {

// Mint the SetToken
_setToken.mint(_to, _quantity);

emit SetTokenIssued(address(_setToken), msg.sender, _to, hookContract, _quantity);
}

Expand Down
22 changes: 22 additions & 0 deletions deployment/approve.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ethers } from "ethers"
import { StandardTokenMock, WETH9 } from "../typechain"
import { Account } from "../utils/test/types"

export async function approveModules({USDC, DAI, BTC, WETH, userOne, module}: IApproveModulesParams){
console.log("Aprroving modules...")
const maxLimit = ethers.constants.MaxUint256
await USDC.connect(userOne.wallet).approve(module, maxLimit)
await DAI.connect(userOne.wallet).approve(module, maxLimit)
await BTC.connect(userOne.wallet).approve(module, maxLimit)
await WETH.connect(userOne.wallet).approve(module, maxLimit)
console.log("Finished aprroving modules!\n")
}

interface IApproveModulesParams{
USDC: StandardTokenMock;
DAI: StandardTokenMock;
BTC: StandardTokenMock;
WETH: WETH9;
userOne: Account;
module: string
}
81 changes: 81 additions & 0 deletions deployment/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { getAccounts } from "../utils/test"
import DeployHelper from "../utils/deploys";
import { ether } from "../utils/index";
import { ethers } from "ethers";
import { SetToken__factory } from "../typechain";
import { approveModules } from "./approve";
import { deployMockTokens } from "./deployMockTokens";
import { deployModules } from "./deployModules";
import { deployCoreContracts } from "./deployCoreContracts";
import { deployOracleAdapter } from "./deployOracleAdapter"

const usdcUSDC = "0xA2F78ab2355fe2f984D808B5CeE7FD0A93D5270E"
const daiUSDC = "0x14866185B1962B63C3Ea9E03Bc1da838bab34C19"
const wbtcUSDC = "0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43"
const ethUSDC = "0x694AA1769357215DE4FAC081bf1f309aDC325306"

const provider = new ethers.providers.JsonRpcProvider("http://127.0.0.1:8545/")

async function deploy(){
try{

const [owner, feeRecipient, userOne] = await getAccounts();
const deployer = new DeployHelper(owner.wallet)
console.log(await provider.getNetwork())

// Deploying the controllerContract
const {controllerContract, setTokenCreator, integrationContract, valuerContract, controllerAddress, tokenCreatorAddress, integrationAddress, valuerAddress} = await deployCoreContracts({deployer, feeAddress:feeRecipient.address})

// Deploying mock tokens
const {USDC, DAI, BTC, WETH, USDCAddress, DAIAddress, BTCAddress, WETHAddress} = await deployMockTokens({deployer, owner: owner.address})

// Deploy Chainlink Price Oracle adaptor

const {USDC_USD, DAI_USDC, ETH_USD, BTC_USD, LINK_USD} = await deployOracleAdapter({deployer})

// Deploying Price Oracle
const priceOracleContract = await deployer.core.deployPriceOracle(controllerAddress, USDCAddress, [],[USDCAddress, DAIAddress, BTCAddress, WETHAddress], [USDCAddress, USDCAddress, USDCAddress, USDCAddress], [USDC_USD, DAI_USDC, BTC_USD, ETH_USD])
console.log("Price Oracle contract address: ", priceOracleContract.address)

// GeneralIndexModule: this will help with rebalance
const {generalIndexContract, issuanceContract, generalIndexAddress, issuanceAddress} = await deployModules({deployer, controllerAddress, WETHAddress})

// Initilaize the Controller contract
await controllerContract.connect(owner.wallet).initialize([tokenCreatorAddress], [generalIndexAddress, issuanceAddress],[integrationAddress, priceOracleContract.address, valuerAddress], [0,1,2])
console.log("Controller has been initialized... \n")

// Deploying SetToken
await setTokenCreator.create([DAIAddress, BTCAddress], [10000,1], [generalIndexAddress, issuanceAddress], owner.address, "ETH-BTC_DAI Index", "EBD")
const vaultAddress = await controllerContract.getSets()
console.log("Token Set - ETH-BTC_DAI Index address", vaultAddress[0], "\n")

// Before issue token, modules must be basicIssuanceModule must be initialized with manager address.
// Initilzing the issuance Module.
await issuanceContract.connect(owner.wallet).initialize(vaultAddress[0], ethers.constants.AddressZero)
// Instance of tokenSet
const vaultContract = new ethers.Contract(vaultAddress[0], SetToken__factory.abi, provider)
console.log(await vaultContract.getComponents())

// Approve module before trying to issuing the tokens.
// To mint 1 token of vault, we need to provide 1ETH, 1 DAI, 1 BTC.
await approveModules({USDC, DAI, BTC, WETH, userOne, module: issuanceAddress})
await DAI.mint(userOne.address, ether(10))
await BTC.mint(userOne.address, ether(10))

// Before balance of userOne
console.log((await vaultContract.balanceOf(userOne.address)).toString())
// Issuing token.
await issuanceContract.connect(userOne.wallet).issue(vaultAddress[0], ether(2), userOne.address)
// After balance
console.log((await vaultContract.balanceOf(userOne.address)).toString())

console.log(await valuerContract.calculateSetTokenValuation(vaultContract.address, USDCAddress))

} catch(e){
console.error(e)
}


}

deploy()
25 changes: 25 additions & 0 deletions deployment/deployCoreContracts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import DeployHelper from "../utils/deploys"

export async function deployCoreContracts({deployer, feeAddress}:ICoreContractsParams){
console.log("Deploying core contracts...")
const controllerContract = await deployer.core.deployController(feeAddress)
const controllerAddress = controllerContract.address
console.log("Controller contract address: ", controllerAddress)
// Deploying setTokenCreator
const setTokenCreator = await deployer.core.deploySetTokenCreator(controllerAddress)
const tokenCreatorAddress = setTokenCreator.address
console.log("Token creator address: ", tokenCreatorAddress)
// Deployiing integration registry
const integrationContract = await deployer.core.deployIntegrationRegistry(controllerAddress)
console.log("Inegration registry contract address: ", integrationContract.address)
// Deploying setValuer contract
const valuerContract = await deployer.core.deploySetValuer(controllerAddress)
console.log("Set vauler contract address: ", valuerContract.address)
console.log("Finished deploying core contracts!\n")

return {controllerContract, setTokenCreator, integrationContract, valuerContract, controllerAddress, tokenCreatorAddress, integrationAddress: integrationContract.address, valuerAddress: valuerContract.address}
}
interface ICoreContractsParams{
deployer:DeployHelper;
feeAddress: string
}
22 changes: 22 additions & 0 deletions deployment/deployMockTokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ether } from "../utils"
import DeployHelper from "../utils/deploys"

export async function deployMockTokens({deployer, owner}: IMockTokensParams){
console.log("Deploying Mock tokens...")
const usdcContract = await deployer.mocks.deployTokenMock(owner, ether(1000000000), 6, "MUSDC Coin", "mUsdc")
const daiContract = await deployer.mocks.deployTokenMock(owner, ether(1000000000), 6, "Mdai Coin", "mdai")
const btcContract = await deployer.mocks.deployTokenMock(owner, ether(1000000000), 18, "MBTC Coin", "mBtc")
const WETH = await deployer.external.deployWETH()
console.log("USDC address: ", usdcContract.address)
console.log("DAI address: ", daiContract.address)
console.log("BTC address: ", btcContract.address)
console.log("WETH address: ", WETH.address)
console.log("Finished deploying mock tokens!\n")
return {DAI:daiContract, USDC:usdcContract, BTC:btcContract, WETH, USDCAddress:usdcContract.address,
DAIAddress:daiContract.address,BTCAddress:btcContract.address, WETHAddress:WETH.address}
}

interface IMockTokensParams{
deployer: DeployHelper;
owner: string;
}
20 changes: 20 additions & 0 deletions deployment/deployModules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import DeployHelper from "../utils/deploys"

export async function deployModules({deployer, controllerAddress, WETHAddress}: IDeployModuleParmas) {
console.log("Deploying modules...")
const generalIndexModuleContract = await deployer.modules.deployGeneralIndexModule(controllerAddress, WETHAddress)
const generalIndexAddress = generalIndexModuleContract.address
console.log("General IndexModule Contract: ", generalIndexAddress)
// BasicIssuanceModule: to mint and redeem set tokens
const basicIssuanceModuleContract = await deployer.modules.deployBasicIssuanceModule(controllerAddress)
const issuanceAddress = basicIssuanceModuleContract.address
console.log("Basic IssuanceModule Contract: ", issuanceAddress )
console.log("Finished deploying modules!\n")
return {generalIndexContract: generalIndexModuleContract, issuanceContract: basicIssuanceModuleContract, generalIndexAddress: generalIndexModuleContract.address, issuanceAddress: basicIssuanceModuleContract.address}
}

interface IDeployModuleParmas{
deployer: DeployHelper;
controllerAddress: string;
WETHAddress: string
}
Loading