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

Atomic curve creation/seeding & ctdl/wbtc curve pool address set into oracles #198

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
eee720c
SC sketch for atomic launch of pool and oracle setting - wip
petrovska-petro Jun 8, 2022
16e11e2
Add IERC20 interface for the right reading of balance of and approvals
petrovska-petro Jun 8, 2022
ec2a14f
Right path for importing chainlink interface
petrovska-petro Jun 8, 2022
ea2187a
Type on the liquidity variable for ctdl
petrovska-petro Jun 8, 2022
4263130
Include governance variable
petrovska-petro Jun 8, 2022
f367bc1
Add using specification for EnumerableSet
petrovska-petro Jun 8, 2022
12ed844
Modify IMedianOracleProvider interface
petrovska-petro Jun 8, 2022
0d6747d
Specify visibility in constants
petrovska-petro Jun 8, 2022
6ee2a20
feat: added tests for atomic launch contract
Fatimanaz Jun 9, 2022
6973082
Introduce the oracle deployment directly from contract
petrovska-petro Jun 10, 2022
419ff35
Add method to init all funding contracts
petrovska-petro Jun 10, 2022
021b263
Add suggestions - Fatima
petrovska-petro Jun 10, 2022
463f532
Remove initialization of fundings from contract, will be handled in m…
petrovska-petro Jun 10, 2022
dfff2cc
fix: updated launch
Fatimanaz Jun 10, 2022
f30a9b6
Explicitly `constant` for wbtcUsdPriceFeed
petrovska-petro Jun 15, 2022
096e3d1
Introduce governance as immutable
petrovska-petro Jun 15, 2022
155c05b
Rounding error suggestion
petrovska-petro Jun 15, 2022
c5aa34e
Use array instead of EnumSet
petrovska-petro Jun 15, 2022
5c02c17
Ensure lp tokens are sent to treasury and check on require
petrovska-petro Jun 15, 2022
688e171
fix: updated test
Fatimanaz Jun 16, 2022
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
246 changes: 246 additions & 0 deletions src/AtomicLaunch.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.12;

import {ChainlinkUtils} from "./oracles/ChainlinkUtils.sol";
import {CtdlWbtcCurveV2Provider} from "./oracles/CtdlWbtcCurveV2Provider.sol";
import {CtdlAssetChainlinkProvider} from "./oracles/CtdlAssetChainlinkProvider.sol";
import {CtdlBtcChainlinkProvider} from "./oracles/CtdlBtcChainlinkProvider.sol";
import {CtdlEthChainlinkProvider} from "./oracles/CtdlEthChainlinkProvider.sol";
import {CtdlWibbtcLpVaultProvider} from "./oracles/CtdlWibbtcLpVaultProvider.sol";

import "./interfaces/erc20/IERC20.sol";
import "./interfaces/curve/ICurvePoolFactory.sol";
import "./interfaces/curve/ICurvePool.sol";
import "./interfaces/chainlink/IAggregatorV3Interface.sol";

contract AtomicLaunch is ChainlinkUtils {
address public citadel;
address public wbtc;

address public constant WBTC_BTC_PRICE_FEED =
0xfdFD9C85aD200c506Cf9e21F1FD8dd01932FBB23;
address public constant BTC_ETH_PRICE_FEED =
0xdeb288F737066589598e9214E782fa5A8eD689e8;

address public constant ETH_USD_PRICE_FEED =
0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419;

address public constant WIBBTC_LP_VAULT =
0xaE96fF08771a109dc6650a1BdCa62F2d558E40af;

address public constant FRAX_ETH_PRICE_FEED =
0x14d04Fff8D21bd62987a5cE9ce543d2F1edF5D3E;
address public constant FRAX_USD_PRICE_FEED =
0xB9E1E3A9feFf48998E45Fa90847ed4D467E8BcfD;

address public constant USDC_ETH_PRICE_FEED =
0x986b5E1e1755e3C2440e960477f25201B0a8bbD4;
address public constant USDC_USD_PRICE_FEED =
0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6;

address public constant CVX_ETH_PRICE_FEED =
0xC9CbF687f43176B302F03f5e58470b77D07c61c6;
address public constant CVX_USD_PRICE_FEED =
0xd962fC30A72A84cE50161031391756Bf2876Af5D;

address public constant BADGER_ETH_PRICE_FEED =
0x58921Ac140522867bf50b9E009599Da0CA4A2379;
address public constant BADGER_USD_PRICE_FEED =
0x66a47b7206130e6FF64854EF0E1EDfa237E65339;

address public constant CURVE_POOL_FACTORY =
0xF18056Bbd320E96A48e3Fbf8bC061322531aac99;
uint256 public constant CITADEL_PRICE = 21;

IAggregatorV3Interface public constant wbtcUsdPriceFeed =
IAggregatorV3Interface(0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c);

/* ========== STATE VARIABLES ========== */
address public immutable governance;
address public immutable treasury;

address[] public oracles;

/* ========== EVENT ========== */
event PoolCreated(address poolAddress);

/// @param _governance Governance allowed to add oracles addresses and trigger launch (governance msig)
constructor(
address _governance,
address _treasury,
address _citadel,
address _wbtc
) {
governance = _governance;
treasury = _treasury;
citadel = _citadel;
wbtc = _wbtc;
}

/***************************************
MODIFIER
****************************************/

modifier onlyGovernance() {
require(msg.sender == governance, "not-governance!");
_;
}

/***************************************
ADMIN - GOVERNANCE
****************************************/

function launch(uint256 citadelToLiquidity, uint256 wbtcToLiquidity)
external
onlyGovernance
{
uint256 initialPoolPrice = _initialPoolPrice();

address[2] memory coins;
coins[0] = citadel;
coins[1] = wbtc;

address poolAddress = ICurvePoolFactory(CURVE_POOL_FACTORY).deploy_pool(
"CTDL/wBTC",
"CTDL",
coins,
400000,
145000000000000,
26000000,
45000000,
2000000000000,
230000000000000,
146000000000000,
5000000000,
600,
initialPoolPrice
);

ICurvePool pool = ICurvePool(poolAddress);

require(
IERC20(citadel).balanceOf(address(this)) >= citadelToLiquidity,
"<citadelToLiquidity!"
);
require(
IERC20(wbtc).balanceOf(address(this)) >= wbtcToLiquidity,
"<wbtcToLiquidity!"
);

IERC20(citadel).approve(poolAddress, citadelToLiquidity);
IERC20(wbtc).approve(poolAddress, wbtcToLiquidity);

uint256[2] memory amounts;
amounts[0] = citadelToLiquidity;
amounts[1] = wbtcToLiquidity;

uint256 lpAmount = pool.add_liquidity(amounts, 0, false, treasury);

require(
pool.balances(0) >= citadelToLiquidity,
"<pool-curve-citadelToLiquidity!"
);
require(
pool.balances(1) >= wbtcToLiquidity,
"<pool-curve-wbtcToLiquidity!"
);
require(
IERC20(pool.token()).balanceOf(treasury) == lpAmount,
"<lpAmount!"
);

_deployOracles(poolAddress);

// NOTE: mainly for clean event, so no needs for mega-detective work
emit PoolCreated(poolAddress);
}

function _initialPoolPrice() internal returns (uint256 _poolPrice) {
(uint256 wbtcOraclePricing, , bool valid) = safeLatestAnswer(
wbtcUsdPriceFeed
);

require(valid, "not-valid!");

_poolPrice =
(wbtcOraclePricing * 1e18) /
10**wbtcUsdPriceFeed.decimals() /
CITADEL_PRICE;
}

function _deployOracles(address _ctdlWbtcCurvePool) internal {
CtdlWbtcCurveV2Provider ctdlWbtcProviderLoc = new CtdlWbtcCurveV2Provider(
_ctdlWbtcCurvePool
);
oracles.push(address(ctdlWbtcProviderLoc));

CtdlBtcChainlinkProvider ctdlBtcProvider = new CtdlBtcChainlinkProvider(
_ctdlWbtcCurvePool,
WBTC_BTC_PRICE_FEED
);
oracles.push(address(ctdlBtcProvider));

CtdlWibbtcLpVaultProvider ctdlWibbtcProvider = new CtdlWibbtcLpVaultProvider(
_ctdlWbtcCurvePool,
WBTC_BTC_PRICE_FEED,
WIBBTC_LP_VAULT
);
oracles.push(address(ctdlWibbtcProvider));

CtdlEthChainlinkProvider ctdlEthProvider1 = new CtdlEthChainlinkProvider(
_ctdlWbtcCurvePool,
WBTC_BTC_PRICE_FEED,
BTC_ETH_PRICE_FEED
);
oracles.push(address(ctdlEthProvider1));

CtdlAssetChainlinkProvider ctdlEthProvider2 = new CtdlAssetChainlinkProvider(
_ctdlWbtcCurvePool,
WBTC_BTC_PRICE_FEED,
address(wbtcUsdPriceFeed),
ETH_USD_PRICE_FEED
petrovska-petro marked this conversation as resolved.
Show resolved Hide resolved
);
oracles.push(address(ctdlEthProvider2));

address[4] memory assetEthFeeds = [
FRAX_ETH_PRICE_FEED,
USDC_ETH_PRICE_FEED,
CVX_ETH_PRICE_FEED,
BADGER_ETH_PRICE_FEED
];

address[4] memory assetUsdFeeds = [
FRAX_USD_PRICE_FEED,
USDC_USD_PRICE_FEED,
CVX_USD_PRICE_FEED,
BADGER_USD_PRICE_FEED
];

for (uint256 i; i < 4; ++i) {
CtdlAssetChainlinkProvider ctdlAssetProvider1 = new CtdlAssetChainlinkProvider(
_ctdlWbtcCurvePool,
WBTC_BTC_PRICE_FEED,
BTC_ETH_PRICE_FEED,
assetUsdFeeds[i]
);
oracles.push(address(ctdlAssetProvider1));

CtdlAssetChainlinkProvider ctdlAssetProvider2 = new CtdlAssetChainlinkProvider(
_ctdlWbtcCurvePool,
WBTC_BTC_PRICE_FEED,
address(wbtcUsdPriceFeed),
assetEthFeeds[i]
);
oracles.push(address(ctdlAssetProvider2));
}
}

/***************************************
PUBLIC FUNCTION
****************************************/

function getAllOracles() public view returns (address[] memory) {
return oracles;
}
}
15 changes: 15 additions & 0 deletions src/interfaces/citadel/IFunding.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT

pragma solidity >=0.5.0 <=0.9.0;

interface IFunding {
function initialize(
address _gac,
address _citadel,
address _asset,
address _xCitadel,
address _saleRecipient,
address _citadelPriceInAssetOracle,
uint256 _assetCap
) external;
}
2 changes: 2 additions & 0 deletions src/interfaces/citadel/IMedianOracleProvider.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ interface IMedianOracleProvider {
);

function latestAnswer() external view returns (uint256);

function setCurvePool(address _pool) external;
}
11 changes: 11 additions & 0 deletions src/interfaces/curve/ICurvePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,15 @@ pragma solidity >=0.5.0 <=0.9.0;

interface ICurvePool {
function get_virtual_price() external view returns (uint256);

function token() external view returns (address);

function add_liquidity(
uint256[2] memory amounts,
uint256 min_mint_amount,
bool use_eth,
address receiver
) external returns (uint256);

function balances(uint256 arg0) external view returns (uint256);
}
20 changes: 20 additions & 0 deletions src/interfaces/curve/ICurvePoolFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <=0.9.0;

interface ICurvePoolFactory {
function deploy_pool(
string memory _name,
string memory _symbol,
address[2] memory _coins,
uint256 A,
uint256 gamma,
uint256 mid_fee,
uint256 out_fee,
uint256 allowed_extra_profit,
uint256 fee_gamma,
uint256 adjustment_step,
uint256 admin_fee,
uint256 ma_half_time,
uint256 initial_price
) external returns (address);
}
Loading