Skip to content

Commit

Permalink
Fixed price oracle tests
Browse files Browse the repository at this point in the history
  • Loading branch information
amit-momin committed Jan 22, 2024
1 parent c335858 commit f58ba41
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 23 deletions.
10 changes: 7 additions & 3 deletions contracts/PriceOracle/PriceOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ contract PriceOracle is Ownable2Step {
error MissingCTokenAddress();

/// @notice UnderlyingAssetDecimals is missing or set to value 0
error InvalidUnderlyingAssetDecimals(uint8 underlyingAssetDecimals);
error InvalidUnderlyingAssetDecimals();

/// @notice Sum of price feed's decimals and underlyingAssetDecimals is greater than MAX_DECIMALS
error FormattingDecimalsTooHigh(uint16 decimals);

/// @notice Price feed missing or duplicated
/// @param priceFeed Price feed address provided
Expand Down Expand Up @@ -201,11 +204,12 @@ contract PriceOracle is Ownable2Step {
* @param underlyingAssetDecimals The underlying asset decimals set in the config
*/
function validateDecimals(address priceFeed, uint8 underlyingAssetDecimals) internal view {
// Check underlyingAssetDecimals exists and non-zero
if (underlyingAssetDecimals <= 0) revert InvalidUnderlyingAssetDecimals();
AggregatorV3Interface aggregator = AggregatorV3Interface(priceFeed);
// Retrieve decimals from feed for formatting
uint8 feedDecimals = aggregator.decimals();
// Check underlyingAssetDecimals exists and non-zero
// Cap the sum of feed decimals and underlying asset decimals to avoid overflows when formatting prices.
if (underlyingAssetDecimals <= 0 || feedDecimals + underlyingAssetDecimals > MAX_DECIMALS) revert InvalidUnderlyingAssetDecimals(underlyingAssetDecimals);
if (feedDecimals + underlyingAssetDecimals > MAX_DECIMALS) revert FormattingDecimalsTooHigh(feedDecimals + underlyingAssetDecimals);
}
}
74 changes: 54 additions & 20 deletions test/PriceOracle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ interface SetupOptions {
isMockedView: boolean;
}

const mockAggregatorAbi = [
export const mockAggregatorAbi = [
{
inputs: [],
name: "latestRoundData",
Expand Down Expand Up @@ -54,10 +54,6 @@ const testConfigMap: Record<
mockPrice: 101000000,
feedDecimals: 8,
},
"0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643": {
mockPrice: 99000000,
feedDecimals: 75,
},
"0xf650C3d88D12dB855b8bf7D11Be6C55A4e07dCC9": {
mockPrice: 99800000,
feedDecimals: 8,
Expand Down Expand Up @@ -87,14 +83,14 @@ async function setup({ isMockedView }: SetupOptions) {
mockAggregatorAbi
);
const testConfig = testConfigMap[config.cToken];
mockedEthAggregator.mock.latestRoundData.returns(
await mockedEthAggregator.mock.latestRoundData.returns(
0,
testConfig.mockPrice,
0,
0,
0
);
mockedEthAggregator.mock.decimals.returns(testConfig.feedDecimals);
await mockedEthAggregator.mock.decimals.returns(testConfig.feedDecimals);
config.priceFeed = mockedEthAggregator.address;
configs.push(config);
}
Expand Down Expand Up @@ -228,12 +224,6 @@ describe("PriceOracle", () => {
await priceOracle.getUnderlyingPrice(batCToken)
);
});
it("should return 0 price for invalid feeds decimal", async () => {
const daiCToken = "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643";
expect(BigNumber.from("0")).to.equal(
await priceOracle.getUnderlyingPrice(daiCToken)
);
});
it("should return 0 price for invalid price from feed", async () => {
const wbtcCToken = "0xccf4429db6322d5c611ee964527d42e5d685dd6a";
expect(BigNumber.from("0")).to.equal(
Expand All @@ -255,10 +245,15 @@ describe("PriceOracle", () => {
});

it("should return success", async () => {
const mockedEthAggregator = await deployMockContract(
deployer,
mockAggregatorAbi
);
await mockedEthAggregator.mock.decimals.returns(8);
const newConfig: TokenConfig = {
cToken: "0x944DD1c7ce133B75880CeE913d513f8C07312393",
underlyingAssetDecimals: "18",
priceFeed: "0x7bAC85A8a13A4BcD8abb3eB7d6b4d632c5a57676",
priceFeed: mockedEthAggregator.address,
};
expect(await priceOracle.addConfig(newConfig))
.to.emit(priceOracle, "PriceOracleAssetAdded")
Expand Down Expand Up @@ -291,14 +286,35 @@ describe("PriceOracle", () => {
);
});
it("should revert for underlyingAssetDecimals too high in config", async () => {
const mockedEthAggregator = await deployMockContract(
deployer,
mockAggregatorAbi
);
await mockedEthAggregator.mock.decimals.returns(8);
const invalidConfig: TokenConfig = {
cToken: "0x041171993284df560249B57358F931D9eB7b925D",
underlyingAssetDecimals: "255",
priceFeed: "0x09023c0da49aaf8fc3fa3adf34c6a7016d38d5e3",
underlyingAssetDecimals: "75",
priceFeed: mockedEthAggregator.address,
};

await expect(priceOracle.addConfig(invalidConfig)).to.be.revertedWith(
"InvalidUnderlyingAssetDecimals"
"FormattingDecimalsTooHigh"
);
});
it("should revert for feed decimals too high", async () => {
const mockedEthAggregator = await deployMockContract(
deployer,
mockAggregatorAbi
);
await mockedEthAggregator.mock.decimals.returns(75);
const invalidConfig: TokenConfig = {
cToken: "0x041171993284df560249B57358F931D9eB7b925D",
underlyingAssetDecimals: "18",
priceFeed: mockedEthAggregator.address,
};

await expect(priceOracle.addConfig(invalidConfig)).to.be.revertedWith(
"FormattingDecimalsTooHigh"
);
});
});
Expand All @@ -310,8 +326,13 @@ describe("PriceOracle", () => {
});

it("should return success", async () => {
const mockedEthAggregator = await deployMockContract(
deployer,
mockAggregatorAbi
);
await mockedEthAggregator.mock.decimals.returns(8);
const existingConfig = parameters[0];
const newPriceFeed = "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6";
const newPriceFeed = mockedEthAggregator.address;
expect(
await priceOracle.updateConfigPriceFeed(
existingConfig.cToken,
Expand All @@ -336,13 +357,26 @@ describe("PriceOracle", () => {
).to.be.revertedWith("UnchangedPriceFeed");
});
it("should revert for missing config", async () => {
const missingCToken = "0x39AA39c021dfbaE8faC545936693aC917d5E7563";
const missingCToken = "0xF5DCe57282A584D2746FaF1593d3121Fcac444dC";
const priceFeed = "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6";

expect(
await expect(
priceOracle.updateConfigPriceFeed(missingCToken, priceFeed)
).to.be.revertedWith("ConfigNotFound");
});
it("should revert for feed decimals too high", async () => {
const mockedEthAggregator = await deployMockContract(
deployer,
mockAggregatorAbi
);
await mockedEthAggregator.mock.decimals.returns(75);
const existingConfig = parameters[0];
const newPriceFeed = mockedEthAggregator.address;

await expect(
priceOracle.updateConfigPriceFeed(existingConfig.cToken, newPriceFeed)
).to.be.revertedWith("FormattingDecimalsTooHigh");
});
});
describe("removeConfig", () => {
beforeEach(async () => {
Expand Down
19 changes: 19 additions & 0 deletions test/PriceOracleConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { smock } from "@defi-wonderland/smock";
import { TokenConfig } from "../configuration/parameters-price-oracle";
import { resetFork } from "./utils";
import { deployMockContract } from "ethereum-waffle";
import { mockAggregatorAbi } from "./PriceOracle.test";

use(smock.matchers);

Expand Down Expand Up @@ -105,6 +107,23 @@ describe("PriceOracle", () => {
new PriceOracle__factory(deployer).deploy(invalidConfigs)
).to.be.revertedWith("InvalidUnderlyingAssetDecimals");
});
it("reverts if feed decimals are too high", async () => {
const mockedEthAggregator = await deployMockContract(
deployer,
mockAggregatorAbi
);
await mockedEthAggregator.mock.decimals.returns(75);
const invalidConfigs: TokenConfig[] = [
{
cToken: "0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5",
underlyingAssetDecimals: "18",
priceFeed: mockedEthAggregator.address,
},
];
await expect(
new PriceOracle__factory(deployer).deploy(invalidConfigs)
).to.be.revertedWith("FormattingDecimalsTooHigh");
});
it("reverts if missing priceFeed", async () => {
const invalidConfigs: TokenConfig[] = [
{
Expand Down

0 comments on commit f58ba41

Please sign in to comment.