Skip to content

Commit

Permalink
feat: add fractional migration
Browse files Browse the repository at this point in the history
  • Loading branch information
rndquu committed Apr 10, 2024
1 parent fc50358 commit a846e62
Show file tree
Hide file tree
Showing 4 changed files with 235 additions and 17 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,20 @@ COLLATERAL_TOKEN_ADDRESS="0x5f98805A4E8be255a32880FDeC7F6728C6568bA0"
# - testnet/anvil: deploys LUSD/USD chainlink price feed from scratch
COLLATERAL_TOKEN_CHAINLINK_PRICE_FEED_ADDRESS="0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0"

# Curve's Governance/WETH pool address.
# Used to fetch Governance/ETH price from built-in oracle.
# By default set to already deployed (production ready) Governance/WETH pool address.
# - mainnet: uses already deployed Governance/ETH pool address
# - testnet/anvil: deploys Governance/WETH pool from scratch
CURVE_GOVERNANCE_WETH_POOL_ADDRESS="0xaCDc85AFCD8B83Eb171AFFCbe29FaD204F6ae45C"

# Chainlink price feed address for ETH/USD pair.
# Used to calculate Governance token price in USD.
# By default set to ETH/USD price feed deployed on ethereum mainnet.
# - mainnet: uses already deployed ETH/USD chainlink price feed
# - testnet/anvil: deploys ETH/USD chainlink price feed from scratch
ETH_USD_CHAINLINK_PRICE_FEED_ADDRESS="0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419"

# Dollar amount in wei minted initially to provide liquidity to the Dollar-3CRV metapool
# By default set to 25k Dollar tokens
INITIAL_DOLLAR_MINT_AMOUNT_WEI="25000000000000000000000"
Expand Down
14 changes: 14 additions & 0 deletions packages/contracts/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ COLLATERAL_TOKEN_ADDRESS="0x5f98805A4E8be255a32880FDeC7F6728C6568bA0"
# - testnet/anvil: deploys LUSD/USD chainlink price feed from scratch
COLLATERAL_TOKEN_CHAINLINK_PRICE_FEED_ADDRESS="0x3D7aE7E594f2f2091Ad8798313450130d0Aba3a0"

# Curve's Governance/WETH pool address.
# Used to fetch Governance/ETH price from built-in oracle.
# By default set to Governance/WETH pool address deployed on ethereum mainnet.
# - mainnet: uses already deployed (production ready) Governance/ETH pool address
# - testnet/anvil: deploys Governance/WETH pool from scratch
CURVE_GOVERNANCE_WETH_POOL_ADDRESS="0xaCDc85AFCD8B83Eb171AFFCbe29FaD204F6ae45C"

# Chainlink price feed address for ETH/USD pair.
# Used to calculate Governance token price in USD.
# By default set to ETH/USD price feed deployed on ethereum mainnet.
# - mainnet: uses already deployed ETH/USD chainlink price feed
# - testnet/anvil: deploys ETH/USD chainlink price feed from scratch
ETH_USD_CHAINLINK_PRICE_FEED_ADDRESS="0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419"

# Dollar amount in wei minted initially to provide liquidity to the Dollar-3CRV metapool
# By default set to 25k Dollar tokens
INITIAL_DOLLAR_MINT_AMOUNT_WEI="25000000000000000000000"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ import {ManagerFacet} from "../../src/dollar/facets/ManagerFacet.sol";
import {OwnershipFacet} from "../../src/dollar/facets/OwnershipFacet.sol";
import {UbiquityPoolFacet} from "../../src/dollar/facets/UbiquityPoolFacet.sol";
import {ICurveStableSwapMetaNG} from "../../src/dollar/interfaces/ICurveStableSwapMetaNG.sol";
import {ICurveTwocryptoOptimized} from "../../src/dollar/interfaces/ICurveTwocryptoOptimized.sol";
import {IDiamondCut} from "../../src/dollar/interfaces/IDiamondCut.sol";
import {IDiamondLoupe} from "../../src/dollar/interfaces/IDiamondLoupe.sol";
import {IERC173} from "../../src/dollar/interfaces/IERC173.sol";
import {DEFAULT_ADMIN_ROLE, DOLLAR_TOKEN_MINTER_ROLE, DOLLAR_TOKEN_BURNER_ROLE, PAUSER_ROLE} from "../../src/dollar/libraries/Constants.sol";
import {DEFAULT_ADMIN_ROLE, DOLLAR_TOKEN_MINTER_ROLE, DOLLAR_TOKEN_BURNER_ROLE, GOVERNANCE_TOKEN_MINTER_ROLE, GOVERNANCE_TOKEN_BURNER_ROLE, PAUSER_ROLE} from "../../src/dollar/libraries/Constants.sol";
import {LibAccessControl} from "../../src/dollar/libraries/LibAccessControl.sol";
import {AppStorage, LibAppStorage, Modifiers} from "../../src/dollar/libraries/LibAppStorage.sol";
import {LibDiamond} from "../../src/dollar/libraries/LibDiamond.sol";
import {MockChainLinkFeed} from "../../src/dollar/mocks/MockChainLinkFeed.sol";
import {MockCurveStableSwapMetaNG} from "../../src/dollar/mocks/MockCurveStableSwapMetaNG.sol";
import {MockCurveTwocryptoOptimized} from "../../src/dollar/mocks/MockCurveTwocryptoOptimized.sol";
import {MockERC20} from "../../src/dollar/mocks/MockERC20.sol";
import {DiamondTestHelper} from "../../test/helpers/DiamondTestHelper.sol";

Expand Down Expand Up @@ -125,9 +127,11 @@ contract Deploy001_Diamond_Dollar_Governance is Script, DiamondTestHelper {
UbiquityPoolFacet ubiquityPoolFacetImplementation;

// oracle related contracts
AggregatorV3Interface chainLinkPriceFeedEth; // chainlink ETH/USD price feed
AggregatorV3Interface chainLinkPriceFeedLusd; // chainlink LUSD/USD price feed
IERC20 curveTriPoolLpToken; // Curve's 3CRV-LP token
ICurveStableSwapMetaNG curveDollarMetaPool; // Curve's Dollar-3CRVLP metapool
ICurveTwocryptoOptimized curveGovernanceEthPool; // Curve's Governance-WETH crypto pool

// collateral ERC20 token used in UbiquityPoolFacet
IERC20 collateralToken;
Expand Down Expand Up @@ -317,6 +321,8 @@ contract Deploy001_Diamond_Dollar_Governance is Script, DiamondTestHelper {
ubiquityPoolFacet.setRedemptionDelayBlocks(2);
// set mint price threshold to $1.01 and redeem price to $0.99
ubiquityPoolFacet.setPriceThresholds(1010000, 990000);
// set collateral ratio to 95%
ubiquityPoolFacet.setCollateralRatio(950_000);

// stop sending admin transactions
vm.stopBroadcast();
Expand Down Expand Up @@ -414,10 +420,20 @@ contract Deploy001_Diamond_Dollar_Governance is Script, DiamondTestHelper {
*
* Development migration deploys (for ease of debugging) mocks of:
* - Chainlink collateral price feed contract
* - Chainlink ETH/USD price feed contract
* - 3CRVLP ERC20 token
* - WETH token
* - Curve's Dollar-3CRVLP metapool contract
* - Curve's Governance-WETH crypto pool contract
*/
function afterRun() public virtual {
UbiquityPoolFacet ubiquityPoolFacet = UbiquityPoolFacet(
address(diamond)
);

// set threshold to 10 years (3650 days) for ease of debugging
CHAINLINK_PRICE_FEED_THRESHOLD = 3650 days;

//========================================
// Chainlink LUSD/USD price feed deploy
//========================================
Expand All @@ -438,9 +454,6 @@ contract Deploy001_Diamond_Dollar_Governance is Script, DiamondTestHelper {
// start sending admin transactions
vm.startBroadcast(adminPrivateKey);

// set threshold to 10 years (3650 days) for ease of debugging
CHAINLINK_PRICE_FEED_THRESHOLD = 3650 days;

// set params for LUSD/USD chainlink price feed mock
MockChainLinkFeed(address(chainLinkPriceFeedLusd)).updateMockParams(
1, // round id
Expand All @@ -450,10 +463,6 @@ contract Deploy001_Diamond_Dollar_Governance is Script, DiamondTestHelper {
1 // answered in round
);

UbiquityPoolFacet ubiquityPoolFacet = UbiquityPoolFacet(
address(diamond)
);

// set price feed address and threshold in seconds
ubiquityPoolFacet.setCollateralChainLinkPriceFeed(
address(collateralToken), // collateral token address
Expand Down Expand Up @@ -532,5 +541,105 @@ contract Deploy001_Diamond_Dollar_Governance is Script, DiamondTestHelper {

// stop sending owner transactions
vm.stopBroadcast();

//==================================
// UbiquityGovernance token setup
//==================================

// start sending admin transactions
vm.startBroadcast(adminPrivateKey);

AccessControlFacet accessControlFacet = AccessControlFacet(
address(diamond)
);

// grant diamond Governance token minting and burning rights
accessControlFacet.grantRole(
GOVERNANCE_TOKEN_MINTER_ROLE,
address(diamond)
);
accessControlFacet.grantRole(
GOVERNANCE_TOKEN_BURNER_ROLE,
address(diamond)
);

// stop sending admin transactions
vm.stopBroadcast();

//=======================================
// Chainlink ETH/USD price feed deploy
//=======================================

// start sending owner transactions
vm.startBroadcast(ownerPrivateKey);

// deploy ETH/USD chainlink mock price feed
chainLinkPriceFeedEth = new MockChainLinkFeed();

// stop sending owner transactions
vm.stopBroadcast();

//======================================
// Chainlink ETH/USD price feed setup
//======================================

// start sending admin transactions
vm.startBroadcast(adminPrivateKey);

// set ETH/USD price feed mock params
MockChainLinkFeed(address(chainLinkPriceFeedEth)).updateMockParams(
1, // round id
3000_00000000, // answer, 3000_00000000 = $3000 (8 decimals)
block.timestamp, // started at
block.timestamp, // updated at
1 // answered in round
);

// set price feed for ETH/USD pair
ubiquityPoolFacet.setEthUsdChainLinkPriceFeed(
address(chainLinkPriceFeedEth), // price feed address
CHAINLINK_PRICE_FEED_THRESHOLD // price feed staleness threshold in seconds
);

// stop sending admin transactions
vm.stopBroadcast();

//==============================================
// Curve's Governance-WETH crypto pool deploy
//==============================================

// start sending owner transactions
vm.startBroadcast(ownerPrivateKey);

// init mock WETH token
IERC20 wethToken = new MockERC20("WETH", "WETH", 18);

// init Curve Governance-WETH crypto pool
curveGovernanceEthPool = new MockCurveTwocryptoOptimized(
address(ubiquityGovernance),
address(wethToken)
);

// stop sending owner transactions
vm.stopBroadcast();

//=============================================
// Curve's Governance-WETH crypto pool setup
//=============================================

// start sending admin transactions
vm.startBroadcast(adminPrivateKey);

// set ETH/Governance price to 30k in Curve pool mock
MockCurveTwocryptoOptimized(address(curveGovernanceEthPool))
.updateMockParams(30_000e18);

// set Governance-ETH pool
ubiquityPoolFacet.setGovernanceEthPoolAddress(
address(curveGovernanceEthPool)
);

// stop sending admin transactions
vm.stopBroadcast();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {ManagerFacet} from "../../src/dollar/facets/ManagerFacet.sol";
import {UbiquityPoolFacet} from "../../src/dollar/facets/UbiquityPoolFacet.sol";
import {ICurveStableSwapFactoryNG} from "../../src/dollar/interfaces/ICurveStableSwapFactoryNG.sol";
import {ICurveStableSwapMetaNG} from "../../src/dollar/interfaces/ICurveStableSwapMetaNG.sol";
import {ICurveTwocryptoOptimized} from "../../src/dollar/interfaces/ICurveTwocryptoOptimized.sol";

/// @notice Migration contract
contract Deploy001_Diamond_Dollar_Governance is
Expand Down Expand Up @@ -68,12 +69,27 @@ contract Deploy001_Diamond_Dollar_Governance is
* - Chainlink collateral price feed contract
* - UbiquityAlgorithmicDollarManager contract
* - UbiquityGovernance token contract
* - Chainlink ETH/USD price feed
* - Curve's Governance-WETH crypto pool
*/
function afterRun() public override {
// read env variables
address chainlinkPriceFeedAddress = vm.envAddress(
address chainlinkPriceFeedAddressEth = vm.envAddress(
"ETH_USD_CHAINLINK_PRICE_FEED_ADDRESS"
);
address chainlinkPriceFeedAddressLusd = vm.envAddress(
"COLLATERAL_TOKEN_CHAINLINK_PRICE_FEED_ADDRESS"
);
address curveGovernanceEthPoolAddress = vm.envAddress(
"CURVE_GOVERNANCE_WETH_POOL_ADDRESS"
);

// set threshold to 1 hour (default value for ETH/USD and LUSD/USD price feeds)
CHAINLINK_PRICE_FEED_THRESHOLD = 1 hours;

UbiquityPoolFacet ubiquityPoolFacet = UbiquityPoolFacet(
address(diamond)
);

//=======================================
// Chainlink LUSD/USD price feed setup
Expand All @@ -82,16 +98,9 @@ contract Deploy001_Diamond_Dollar_Governance is
// start sending admin transactions
vm.startBroadcast(adminPrivateKey);

// set threshold to 1 day
CHAINLINK_PRICE_FEED_THRESHOLD = 1 days;

// init LUSD/USD chainlink price feed
chainLinkPriceFeedLusd = AggregatorV3Interface(
chainlinkPriceFeedAddress
);

UbiquityPoolFacet ubiquityPoolFacet = UbiquityPoolFacet(
address(diamond)
chainlinkPriceFeedAddressLusd
);

// set price feed
Expand Down Expand Up @@ -162,9 +171,81 @@ contract Deploy001_Diamond_Dollar_Governance is
// UbiquityGovernance setup
//============================

// NOTICE: If owner address is `ubq.eth` (i.e. ubiquity deployer) it means that we want to perform
// a real deployment to mainnet so we start sending transactions via `startBroadcast()` otherwise
// we're in the forked mainnet anvil instance so we simulate sending transactions from `ubq.eth`
// address for ease of debugging.
address ubiquityDeployerAddress = 0xefC0e701A824943b469a694aC564Aa1efF7Ab7dd;

// Start sending owner transactions
if (ownerAddress == ubiquityDeployerAddress) {
vm.startBroadcast(ownerPrivateKey);
} else {
vm.startPrank(ubiquityDeployerAddress);
}

// using already deployed (on mainnet) Governance token
ubiquityGovernance = UbiquityGovernance(
0x4e38D89362f7e5db0096CE44ebD021c3962aA9a0
);

// Owner (i.e. `ubq.eth` who is admin for UbiquityAlgorithmicDollarManager) grants diamond
// Governance token mint and burn rights
ubiquityAlgorithmicDollarManager.grantRole(
keccak256("UBQ_MINTER_ROLE"),
address(diamond)
);
ubiquityAlgorithmicDollarManager.grantRole(
keccak256("UBQ_BURNER_ROLE"),
address(diamond)
);

// stop sending owner transactions
if (ownerAddress == ubiquityDeployerAddress) {
vm.stopBroadcast();
} else {
vm.stopPrank();
}

//======================================
// Chainlink ETH/USD price feed setup
//======================================

// start sending admin transactions
vm.startBroadcast(adminPrivateKey);

// init ETH/USD chainlink price feed
chainLinkPriceFeedEth = AggregatorV3Interface(
chainlinkPriceFeedAddressEth
);

// set price feed for ETH/USD pair
ubiquityPoolFacet.setEthUsdChainLinkPriceFeed(
address(chainLinkPriceFeedEth), // price feed address
CHAINLINK_PRICE_FEED_THRESHOLD // price feed staleness threshold in seconds
);

// stop sending admin transactions
vm.stopBroadcast();

//=============================================
// Curve's Governance-WETH crypto pool setup
//=============================================

// start sending admin transactions
vm.startBroadcast(adminPrivateKey);

// init Curve Governance-WETH crypto pool
curveGovernanceEthPool = ICurveTwocryptoOptimized(
curveGovernanceEthPoolAddress
);

// set Governance-ETH pool
ubiquityPoolFacet.setGovernanceEthPoolAddress(
address(curveGovernanceEthPool)
);

// stop sending admin transactions
vm.stopBroadcast();
}
}

0 comments on commit a846e62

Please sign in to comment.