Skip to content
This repository was archived by the owner on Aug 26, 2024. It is now read-only.

Commit a0a70db

Browse files
committed
feat: deploy aero oracle
1 parent d7a7826 commit a0a70db

File tree

13 files changed

+1849
-726
lines changed

13 files changed

+1849
-726
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { addTransaction, prepareAndLogTransaction } from "../logging";
2+
import {
3+
AerodromeDeployFnParams,
4+
ChainlinkAsset,
5+
ChainlinkDeployFnParams,
6+
ChainlinkFeedBaseCurrency
7+
} from "../../../chains/types";
8+
9+
import { addUnderlyingsToMpo } from "./utils";
10+
import { Address, encodeFunctionData } from "viem";
11+
import { underlying } from "../utils";
12+
import { DeployResult } from "hardhat-deploy/types";
13+
14+
export const deployAerodromeOracle = async ({
15+
viem,
16+
getNamedAccounts,
17+
deployments,
18+
pricesContract,
19+
assets
20+
}: AerodromeDeployFnParams): Promise<{ apo: DeployResult }> => {
21+
const { deployer } = await getNamedAccounts();
22+
const publicClient = await viem.getPublicClient();
23+
const walletClient = await viem.getWalletClient(deployer as Address);
24+
let tx;
25+
26+
//// Aerodrome Oracle
27+
const apo = await deployments.deploy("AerodromePriceOracle", {
28+
from: deployer,
29+
args: [pricesContract],
30+
log: true,
31+
waitConfirmations: 1
32+
});
33+
if (apo.transactionHash) await publicClient.waitForTransactionReceipt({ hash: apo.transactionHash as Address });
34+
console.log("ChainlinkPriceOracleV2: ", apo.address);
35+
36+
const aerodrome = await viem.getContractAt(
37+
"AerodromePriceOracle",
38+
(await deployments.get("AerodromePriceOracle")).address as Address
39+
);
40+
41+
const underlyings = assets.map((c) => underlying(assets, c.symbol));
42+
43+
const mpo = await viem.getContractAt(
44+
"MasterPriceOracle",
45+
(await deployments.get("MasterPriceOracle")).address as Address
46+
);
47+
await addUnderlyingsToMpo(mpo as any, underlyings, aerodrome.address, deployer, publicClient, walletClient);
48+
49+
const addressesProvider = await viem.getContractAt(
50+
"AddressesProvider",
51+
(await deployments.get("AddressesProvider")).address as Address
52+
);
53+
const aerodromeAddress = await addressesProvider.read.getAddress(["AerodromePriceOracle"]);
54+
if (aerodromeAddress !== aerodrome.address) {
55+
if (((await addressesProvider.read.owner()) as Address).toLowerCase() === deployer.toLowerCase()) {
56+
tx = await addressesProvider.write.setAddress(["AerodromePriceOracle", aerodrome.address]);
57+
await publicClient.waitForTransactionReceipt({ hash: tx });
58+
console.log(`setAddress AerodromePriceOracle at ${tx}`);
59+
} else {
60+
prepareAndLogTransaction({
61+
contractInstance: addressesProvider,
62+
functionName: "setAddress",
63+
args: ["AerodromePriceOracle", aerodrome.address],
64+
description: "Set AerodromePriceOracle address on AddressProvider",
65+
inputs: [
66+
{ internalType: "string", name: "id", type: "string" },
67+
{ internalType: "address", name: "newAddress", type: "address" }
68+
]
69+
});
70+
console.log("Logged Transaction to setAddress ChainlinkPriceOracleV2 on AddressProvider");
71+
}
72+
}
73+
74+
return { apo };
75+
};

chainDeploy/mainnets/base.ts

Lines changed: 58 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,65 @@
1-
// import { ChainDeployConfig, deployChainlinkOracle } from "../helpers";
2-
// import { ChainlinkAsset } from "../../chains/types";
1+
import { ChainDeployConfig } from "../helpers";
2+
import { OracleTypes, SupportedAsset } from "../../chains/types";
3+
import { base } from "../../chains";
4+
import { deployAerodromeOracle } from "../helpers/oracles/aerodrome";
5+
import { HardhatRuntimeEnvironment } from "hardhat/types";
36

4-
// const assets = base.assets;
7+
const assets = base.assets;
58

6-
// export const deployConfig: ChainDeployConfig = {
7-
// blocksPerYear: Number(base.specificParams.blocksPerYear),
8-
// cgId: base.specificParams.cgId,
9-
// nativeTokenName: "Base",
10-
// nativeTokenSymbol: "ETH",
11-
// stableToken: base.chainAddresses.STABLE_TOKEN,
12-
// uniswap: {
13-
// flashSwapFee: 30, // TODO set the correct fee
14-
// hardcoded: [],
15-
// uniswapData: [],
16-
// uniswapOracleInitialDeployTokens: [],
17-
// uniswapV2FactoryAddress: "0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6",
18-
// uniswapV2RouterAddress: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
19-
// uniswapV3SwapRouter: "0x2626664c2603336E57B271c5C0b26F421741e481",
20-
// uniswapV3Quoter: "0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a"
21-
// },
22-
// wtoken: base.chainAddresses.W_TOKEN,
23-
// nativeTokenUsdChainlinkFeed: base.chainAddresses.W_TOKEN_USD_CHAINLINK_PRICE_FEED
24-
// };
9+
const pricesContract = "0xee717411f6E44F9feE011835C8E6FAaC5dEfF166";
2510

26-
// const chainlinkAssets: ChainlinkAsset[] = base.assets
27-
// .filter((asset) => asset.oracle === OracleTypes.ChainlinkPriceOracleV2)
28-
// .map((asset) => ({
29-
// aggregator: (asset.oracleSpecificParams as ChainlinkSpecificParams).aggregator,
30-
// feedBaseCurrency: (asset.oracleSpecificParams as ChainlinkSpecificParams).feedBaseCurrency,
31-
// symbol: asset.symbol
32-
// }));
11+
export const deployConfig: ChainDeployConfig = {
12+
blocksPerYear: Number(base.specificParams.blocksPerYear),
13+
cgId: base.specificParams.cgId,
14+
nativeTokenName: "Base",
15+
nativeTokenSymbol: "ETH",
16+
stableToken: base.chainAddresses.STABLE_TOKEN,
17+
uniswap: {
18+
flashSwapFee: 30, // TODO set the correct fee
19+
hardcoded: [],
20+
uniswapData: [],
21+
uniswapOracleInitialDeployTokens: [],
22+
uniswapV2FactoryAddress: "0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6",
23+
uniswapV2RouterAddress: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",
24+
uniswapV3SwapRouter: "0x2626664c2603336E57B271c5C0b26F421741e481",
25+
uniswapV3Quoter: "0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a"
26+
},
27+
wtoken: base.chainAddresses.W_TOKEN,
28+
nativeTokenUsdChainlinkFeed: base.chainAddresses.W_TOKEN_USD_CHAINLINK_PRICE_FEED
29+
};
3330

34-
// export const deploy = async ({ run, ethers, getNamedAccounts, deployments }): Promise<void> => {
35-
// const { deployer } = await getNamedAccounts();
31+
const aerodromeAssets: SupportedAsset[] = base.assets.filter(
32+
(asset) => asset.oracle === OracleTypes.AerodromePriceOracle
33+
);
3634

37-
// //// ChainLinkV2 Oracle
38-
// await deployChainlinkOracle({
39-
// run,
40-
// ethers,
41-
// getNamedAccounts,
42-
// deployments,
43-
// deployConfig,
44-
// assets,
45-
// chainlinkAssets
46-
// });
35+
export const deploy = async ({ run, viem, getNamedAccounts, deployments }: HardhatRuntimeEnvironment): Promise<void> => {
36+
const { deployer } = await getNamedAccounts();
4737

48-
// //// Uniswap V3 Liquidator Funder
49-
// const uniswapV3LiquidatorFunder = await deployments.deploy("UniswapV3LiquidatorFunder", {
50-
// from: deployer,
51-
// args: [],
52-
// log: true,
53-
// waitConfirmations: 1
54-
// });
55-
// console.log("UniswapV3LiquidatorFunder: ", uniswapV3LiquidatorFunder.address);
38+
//// ChainLinkV2 Oracle
39+
await deployAerodromeOracle({
40+
run,
41+
viem,
42+
getNamedAccounts,
43+
deployments,
44+
deployConfig,
45+
assets: aerodromeAssets,
46+
pricesContract
47+
});
5648

57-
// const solidlySwapLiquidator = await deployments.deploy("SolidlySwapLiquidator", {
58-
// from: deployer,
59-
// args: [],
60-
// log: true,
61-
// waitConfirmations: 1
62-
// });
63-
// console.log("solidlySwapLiquidator: ", solidlySwapLiquidator.address);
64-
// };
49+
//// Uniswap V3 Liquidator Funder
50+
const uniswapV3LiquidatorFunder = await deployments.deploy("UniswapV3LiquidatorFunder", {
51+
from: deployer,
52+
args: [],
53+
log: true,
54+
waitConfirmations: 1
55+
});
56+
console.log("UniswapV3LiquidatorFunder: ", uniswapV3LiquidatorFunder.address);
57+
58+
const solidlySwapLiquidator = await deployments.deploy("SolidlySwapLiquidator", {
59+
from: deployer,
60+
args: [],
61+
log: true,
62+
waitConfirmations: 1
63+
});
64+
console.log("solidlySwapLiquidator: ", solidlySwapLiquidator.address);
65+
};

chainDeploy/mainnets/mode.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Hash, zeroAddress } from "viem";
22

33
import { ChainDeployConfig, deployChainlinkOracle, deployPythPriceOracle } from "../helpers";
4-
import { writeTransactionsToFile } from "../helpers/logging";
54
import { addRedstoneFallbacks } from "../helpers/oracles/redstoneFallbacks";
65
import { addRedstoneWeETHFallbacks } from "../helpers/oracles/redstoneWeETHFallbacks";
76
import { deployRedStoneWrsETHPriceOracle } from "../helpers/oracles/redstoneWrsETH";
@@ -145,5 +144,4 @@ export const deploy = async ({
145144
await publicClient.waitForTransactionReceipt({ hash: algebraSwapLiquidator.transactionHash as Hash });
146145
}
147146
console.log("AlgebraSwapLiquidator: ", algebraSwapLiquidator.address);
148-
await writeTransactionsToFile();
149147
};

chains/assets.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ export enum assetSymbols {
1616
OP = "OP",
1717
LUSD = "LUSD",
1818
SOV = "SOV",
19-
tBTC = "tBTC"
19+
tBTC = "tBTC",
20+
ION = "ION"
2021
}

chains/base/assets.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export const WBTC = "0x1ceA84203673764244E05693e42E6Ace62bE9BA5";
1313
export const weETH = "0x04C0599Ae5A44757c0af6F9eC3b93da8976c150A";
1414
export const eUSD = "0xcfa3ef56d303ae4faaba0592388f19d7c3399fb4";
1515
export const bsdETH = "0xcb327b99ff831bf8223cced12b1338ff3aa322ff";
16+
export const ION = "0x3eE5e23eEE121094f1cFc0Ccc79d6C809Ebd22e5";
1617

1718
export const assets: SupportedAsset[] = [
1819
{
@@ -138,6 +139,13 @@ export const assets: SupportedAsset[] = [
138139
initialSupplyCap: parseEther(String(6_500)).toString(),
139140
initialBorrowCap: parseEther(String(5_200)).toString(),
140141
initialCf: "70"
142+
},
143+
{
144+
symbol: assetSymbols.ION,
145+
underlying: ION,
146+
name: "Ionic",
147+
decimals: 18,
148+
oracle: OracleTypes.AerodromePriceOracle
141149
}
142150
];
143151

chains/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { default as mode } from "./mode";
2+
import { default as base } from "./base";
23
import { ChainConfig } from "./types";
34

4-
export { mode };
5+
export { mode, base };
56

67
export const chainIdToConfig: { [chainId: number]: ChainConfig } = {
7-
[mode.chainId]: mode
8+
[mode.chainId]: mode,
9+
[base.chainId]: base
810
};

chains/types.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,12 @@ export type ChainlinkDeployFnParams = ChainDeployFnParams & {
168168
deployConfig: ChainDeployConfig;
169169
};
170170

171+
export type AerodromeDeployFnParams = ChainDeployFnParams & {
172+
assets: SupportedAsset[];
173+
pricesContract: Address;
174+
deployConfig: ChainDeployConfig;
175+
};
176+
171177
export type DiaDeployFnParams = ChainDeployFnParams & {
172178
diaAssets: DiaAsset[];
173179
deployConfig: ChainDeployConfig;
@@ -281,6 +287,10 @@ export type PythSpecificParams = {
281287
feed: string;
282288
};
283289

290+
export type VelodromeSpecificParams = {
291+
pricesContract: Address;
292+
};
293+
284294
export type SupportedAsset = {
285295
symbol: string;
286296
underlying: Address;
@@ -291,7 +301,7 @@ export type SupportedAsset = {
291301
oracle?: OracleTypes;
292302
simplePriceOracleAssetPrice?: bigint;
293303
originalSymbol?: string;
294-
oracleSpecificParams?: ChainlinkSpecificParams | PythSpecificParams;
304+
oracleSpecificParams?: ChainlinkSpecificParams | PythSpecificParams | VelodromeSpecificParams;
295305
initialCf?: string;
296306
initialBorrowCap?: string;
297307
initialSupplyCap?: string;
@@ -309,7 +319,9 @@ export enum OracleTypes {
309319
ERC4626Oracle = "ERC4626Oracle",
310320
PythPriceOracle = "PythPriceOracle",
311321
RedstoneAdapterPriceOracle = "RedstoneAdapterPriceOracle",
312-
RedstoneAdapterWrsETHPriceOracle = "RedstoneAdapterWrsETHPriceOracle"
322+
RedstoneAdapterWrsETHPriceOracle = "RedstoneAdapterWrsETHPriceOracle",
323+
VelodromePriceOracle = "VelodromePriceOracle",
324+
AerodromePriceOracle = "AerodromePriceOracle"
313325
}
314326

315327
export type ChainAddresses = {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity >=0.8.0;
3+
4+
import "../BasePriceOracle.sol";
5+
6+
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
7+
8+
interface BasePrices {
9+
function getManyRatesWithConnectors(
10+
uint8 src_len,
11+
address[] memory connectors
12+
) external view returns (uint256[] memory rates);
13+
}
14+
15+
contract AerodromePriceOracle is BasePriceOracle {
16+
BasePrices immutable prices;
17+
address constant WETH = 0x4200000000000000000000000000000000000006;
18+
19+
constructor(address _prices) {
20+
prices = BasePrices(_prices);
21+
}
22+
23+
/**
24+
* @notice Fetches the token/ETH price, with 18 decimals of precision.
25+
* @param underlying The underlying token address for which to get the price.
26+
* @return Price denominated in ETH (scaled by 1e18)
27+
*/
28+
function price(address underlying) external view override returns (uint256) {
29+
return _price(underlying);
30+
}
31+
32+
/**
33+
* @notice Returns the price in ETH of the token underlying `cToken`.
34+
* @dev Implements the `PriceOracle` interface for Ionic pools (and Compound v2).
35+
* @return Price in ETH of the token underlying `cToken`, scaled by `10 ** (36 - underlyingDecimals)`.
36+
*/
37+
function getUnderlyingPrice(ICErc20 cToken) external view override returns (uint256) {
38+
address underlying = cToken.underlying();
39+
// Comptroller needs prices to be scaled by 1e(36 - decimals)
40+
// Since `_price` returns prices scaled by 18 decimals, we must scale them by 1e(36 - 18 - decimals)
41+
return (_price(underlying));
42+
}
43+
44+
/**
45+
* @notice Fetches the token/ETH price, with 18 decimals of precision.
46+
*/
47+
function _price(address token) internal view returns (uint256) {
48+
address[] memory connectors = new address[](2);
49+
connectors[0] = token;
50+
connectors[1] = WETH;
51+
return prices.getManyRatesWithConnectors(1, connectors)[0];
52+
}
53+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity >=0.8.0;
3+
4+
import "../BasePriceOracle.sol";
5+
6+
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
7+
8+
interface Prices {
9+
function getRateToEth(address srcToken, bool useSrcWrappers) external view returns (uint256 weightedRate);
10+
}
11+
12+
contract VelodromePriceOracle is BasePriceOracle {
13+
Prices immutable prices;
14+
15+
constructor(address _prices) {
16+
prices = Prices(_prices);
17+
}
18+
/**
19+
* @notice Fetches the token/ETH price, with 18 decimals of precision.
20+
* @param underlying The underlying token address for which to get the price.
21+
* @return Price denominated in ETH (scaled by 1e18)
22+
*/
23+
function price(address underlying) external view override returns (uint256) {
24+
return _price(underlying);
25+
}
26+
27+
/**
28+
* @notice Returns the price in ETH of the token underlying `cToken`.
29+
* @dev Implements the `PriceOracle` interface for Ionic pools (and Compound v2).
30+
* @return Price in ETH of the token underlying `cToken`, scaled by `10 ** (36 - underlyingDecimals)`.
31+
*/
32+
function getUnderlyingPrice(ICErc20 cToken) external view override returns (uint256) {
33+
address underlying = cToken.underlying();
34+
// Comptroller needs prices to be scaled by 1e(36 - decimals)
35+
// Since `_price` returns prices scaled by 18 decimals, we must scale them by 1e(36 - 18 - decimals)
36+
return (_price(underlying));
37+
}
38+
39+
/**
40+
* @notice Fetches the token/ETH price, with 18 decimals of precision.
41+
*/
42+
function _price(address token) internal view returns (uint256) {
43+
return prices.getRateToEth(token, false);
44+
}
45+
}

0 commit comments

Comments
 (0)