Skip to content

Commit

Permalink
Change contract name ChainlinkPriceFeedWithCachedTwap to `Chainlink…
Browse files Browse the repository at this point in the history
…PriceFeedV2`, add IPriceFeedV2
  • Loading branch information
Opass Chang committed May 23, 2022
1 parent f17b691 commit f6ceba7
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 59 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [unreleased]
- Change contract name `ChainlinkPriceFeed` to `ChainlinkPriceFeedWithCachedTwap`.
- Change contract name `ChainlinkPriceFeed` to `ChainlinkPriceFeedV2`.
- Add origin `ChainlinkPriceFeed`, which calculates the twap by round data instead of cached twap.

## [0.3.4] - 2022-04-01
Expand Down
4 changes: 2 additions & 2 deletions contracts/BandPriceFeed.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ pragma experimental ABIEncoderV2;

import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { BlockContext } from "./base/BlockContext.sol";
import { IPriceFeed } from "./interface/IPriceFeed.sol";
import { IPriceFeedV2 } from "./interface/IPriceFeedV2.sol";
import { IStdReference } from "./interface/bandProtocol/IStdReference.sol";
import { CachedTwap } from "./twap/CachedTwap.sol";

contract BandPriceFeed is IPriceFeed, BlockContext, CachedTwap {
contract BandPriceFeed is IPriceFeedV2, BlockContext, CachedTwap {
using Address for address;

//
Expand Down
6 changes: 0 additions & 6 deletions contracts/ChainlinkPriceFeed.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ contract ChainlinkPriceFeed is IPriceFeed, BlockContext {
_aggregator = aggregator;
}

/// @dev not support cached twap
function cacheTwap(uint256 interval) external override returns (uint256) {
// CPF_NS: not supported
revert("CPF_NS");
}

function decimals() external view override returns (uint8) {
return _aggregator.decimals();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ pragma solidity 0.7.6;

import { Address } from "@openzeppelin/contracts/utils/Address.sol";
import { AggregatorV3Interface } from "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
import { IPriceFeed } from "./interface/IPriceFeed.sol";
import { IPriceFeedV2 } from "./interface/IPriceFeedV2.sol";
import { BlockContext } from "./base/BlockContext.sol";
import { CachedTwap } from "./twap/CachedTwap.sol";

contract ChainlinkPriceFeedWithCachedTwap is IPriceFeed, BlockContext, CachedTwap {
contract ChainlinkPriceFeedV2 is IPriceFeedV2, BlockContext, CachedTwap {
using Address for address;

AggregatorV3Interface private immutable _aggregator;
Expand Down
4 changes: 2 additions & 2 deletions contracts/EmergencyPriceFeed.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { IUniswapV3Pool } from "@uniswap/v3-core/contracts/interfaces/IUniswapV3
import { FixedPoint96 } from "@uniswap/v3-core/contracts/libraries/FixedPoint96.sol";
import { FullMath } from "@uniswap/v3-core/contracts/libraries/FullMath.sol";
import { TickMath } from "@uniswap/v3-core/contracts/libraries/TickMath.sol";
import { IPriceFeed } from "./interface/IPriceFeed.sol";
import { IPriceFeedV2 } from "./interface/IPriceFeedV2.sol";
import { BlockContext } from "./base/BlockContext.sol";

contract EmergencyPriceFeed is IPriceFeed, BlockContext {
contract EmergencyPriceFeed is IPriceFeedV2, BlockContext {
using Address for address;

//
Expand Down
4 changes: 0 additions & 4 deletions contracts/interface/IPriceFeed.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
pragma solidity 0.7.6;

interface IPriceFeed {
/// @dev Returns the cached index price of the token.
/// @param interval The interval represents twap interval.
function cacheTwap(uint256 interval) external returns (uint256);

function decimals() external view returns (uint8);

/// @dev Returns the index price of the token.
Expand Down
10 changes: 10 additions & 0 deletions contracts/interface/IPriceFeedV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.7.6;

import "./IPriceFeed.sol";

interface IPriceFeedV2 is IPriceFeed {
/// @dev Returns the cached index price of the token.
/// @param interval The interval represents twap interval.
function cacheTwap(uint256 interval) external returns (uint256);
}
22 changes: 11 additions & 11 deletions contracts/test/TestPriceFeed.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.7.6;

import { IPriceFeed } from "../interface/IPriceFeed.sol";
import { IPriceFeedV2 } from "../interface/IPriceFeedV2.sol";

contract TestPriceFeed {
address public chainlink;
Expand All @@ -20,30 +20,30 @@ contract TestPriceFeed {
//
function fetchChainlinkPrice(uint256 interval) external {
for (uint256 i = 0; i < 17; i++) {
IPriceFeed(chainlink).getPrice(interval);
IPriceFeedV2(chainlink).getPrice(interval);
}
currentPrice = IPriceFeed(chainlink).getPrice(interval);
currentPrice = IPriceFeedV2(chainlink).getPrice(interval);
}

function fetchBandProtocolPrice(uint256 interval) external {
for (uint256 i = 0; i < 17; i++) {
IPriceFeed(bandProtocol).getPrice(interval);
IPriceFeedV2(bandProtocol).getPrice(interval);
}
currentPrice = IPriceFeed(bandProtocol).getPrice(interval);
currentPrice = IPriceFeedV2(bandProtocol).getPrice(interval);
}

function cachedChainlinkPrice(uint256 interval) external {
for (uint256 i = 0; i < 17; i++) {
IPriceFeed(chainlink).cacheTwap(interval);
IPriceFeedV2(chainlink).cacheTwap(interval);
}
currentPrice = IPriceFeed(chainlink).cacheTwap(interval);
currentPrice = IPriceFeedV2(chainlink).cacheTwap(interval);
}

function cachedBandProtocolPrice(uint256 interval) external {
for (uint256 i = 0; i < 17; i++) {
IPriceFeed(bandProtocol).cacheTwap(interval);
IPriceFeedV2(bandProtocol).cacheTwap(interval);
}
currentPrice = IPriceFeed(bandProtocol).cacheTwap(interval);
currentPrice = IPriceFeedV2(bandProtocol).cacheTwap(interval);
}

//
Expand All @@ -53,7 +53,7 @@ contract TestPriceFeed {
// having this function for testing getPrice() and cacheTwap()
// timestamp moves if any txs happen in hardhat env and which causes cacheTwap() will recalculate all the time
function getPrice(uint256 interval) external returns (uint256 twap, uint256 cachedTwap) {
twap = IPriceFeed(bandProtocol).getPrice(interval);
cachedTwap = IPriceFeed(bandProtocol).cacheTwap(interval);
twap = IPriceFeedV2(bandProtocol).getPrice(interval);
cachedTwap = IPriceFeedV2(bandProtocol).cacheTwap(interval);
}
}
16 changes: 5 additions & 11 deletions test/CachedTwap.spec.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import { expect } from "chai"
import { parseEther } from "ethers/lib/utils"
import { ethers, waffle } from "hardhat"
import {
BandPriceFeed,
ChainlinkPriceFeedWithCachedTwap,
TestAggregatorV3,
TestPriceFeed,
TestStdReference,
} from "../typechain"
import { BandPriceFeed, ChainlinkPriceFeedV2, TestAggregatorV3, TestPriceFeed, TestStdReference } from "../typechain"

interface PriceFeedFixture {
bandPriceFeed: BandPriceFeed
bandReference: TestStdReference
baseAsset: string

// chainlinik
chainlinkPriceFeed: ChainlinkPriceFeedWithCachedTwap
chainlinkPriceFeed: ChainlinkPriceFeedV2
aggregator: TestAggregatorV3
}
async function priceFeedFixture(): Promise<PriceFeedFixture> {
Expand All @@ -36,11 +30,11 @@ async function priceFeedFixture(): Promise<PriceFeedFixture> {
const testAggregatorFactory = await ethers.getContractFactory("TestAggregatorV3")
const testAggregator = await testAggregatorFactory.deploy()

const chainlinkPriceFeedFactory = await ethers.getContractFactory("ChainlinkPriceFeedWithCachedTwap")
const chainlinkPriceFeedFactory = await ethers.getContractFactory("ChainlinkPriceFeedV2")
const chainlinkPriceFeed = (await chainlinkPriceFeedFactory.deploy(
testAggregator.address,
twapInterval,
)) as ChainlinkPriceFeedWithCachedTwap
)) as ChainlinkPriceFeedV2

return { bandPriceFeed, bandReference: testStdReference, baseAsset, chainlinkPriceFeed, aggregator: testAggregator }
}
Expand All @@ -50,7 +44,7 @@ describe("Cached Twap Spec", () => {
const loadFixture: ReturnType<typeof waffle.createFixtureLoader> = waffle.createFixtureLoader([admin])
let bandPriceFeed: BandPriceFeed
let bandReference: TestStdReference
let chainlinkPriceFeed: ChainlinkPriceFeedWithCachedTwap
let chainlinkPriceFeed: ChainlinkPriceFeedV2
let aggregator: TestAggregatorV3
let currentTime: number
let testPriceFeed: TestPriceFeed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,27 @@ import { FakeContract, smock } from "@defi-wonderland/smock"
import { expect } from "chai"
import { parseEther } from "ethers/lib/utils"
import { ethers, waffle } from "hardhat"
import { ChainlinkPriceFeedWithCachedTwap, TestAggregatorV3 } from "../typechain"
import { ChainlinkPriceFeedV2, TestAggregatorV3 } from "../typechain"

interface ChainlinkPriceFeedFixture {
chainlinkPriceFeed: ChainlinkPriceFeedWithCachedTwap
chainlinkPriceFeed: ChainlinkPriceFeedV2
aggregator: FakeContract<TestAggregatorV3>
}

async function chainlinkPriceFeedFixture(): Promise<ChainlinkPriceFeedFixture> {
const aggregator = await smock.fake<TestAggregatorV3>("TestAggregatorV3")
aggregator.decimals.returns(() => 18)

const chainlinkPriceFeedFactory = await ethers.getContractFactory("ChainlinkPriceFeedWithCachedTwap")
const chainlinkPriceFeed = (await chainlinkPriceFeedFactory.deploy(
aggregator.address,
900,
)) as ChainlinkPriceFeedWithCachedTwap
const chainlinkPriceFeedFactory = await ethers.getContractFactory("ChainlinkPriceFeedV2")
const chainlinkPriceFeed = (await chainlinkPriceFeedFactory.deploy(aggregator.address, 900)) as ChainlinkPriceFeedV2

return { chainlinkPriceFeed, aggregator }
}

describe("ChainlinkPriceFeedWithCachedTwap Spec", () => {
describe("ChainlinkPriceFeedV2 Spec", () => {
const [admin] = waffle.provider.getWallets()
const loadFixture: ReturnType<typeof waffle.createFixtureLoader> = waffle.createFixtureLoader([admin])
let chainlinkPriceFeed: ChainlinkPriceFeedWithCachedTwap
let chainlinkPriceFeed: ChainlinkPriceFeedV2
let aggregator: FakeContract<TestAggregatorV3>
let currentTime: number
let roundData: any[]
Expand Down
16 changes: 5 additions & 11 deletions test/PriceFeed.gas.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { parseEther } from "ethers/lib/utils"
import { ethers, waffle } from "hardhat"
import {
BandPriceFeed,
ChainlinkPriceFeedWithCachedTwap,
TestAggregatorV3,
TestPriceFeed,
TestStdReference,
} from "../typechain"
import { BandPriceFeed, ChainlinkPriceFeedV2, TestAggregatorV3, TestPriceFeed, TestStdReference } from "../typechain"

const twapInterval = 900
interface PriceFeedFixture {
Expand All @@ -15,7 +9,7 @@ interface PriceFeedFixture {
baseAsset: string

// chainlinik
chainlinkPriceFeed: ChainlinkPriceFeedWithCachedTwap
chainlinkPriceFeed: ChainlinkPriceFeedV2
aggregator: TestAggregatorV3
}

Expand All @@ -36,11 +30,11 @@ async function priceFeedFixture(): Promise<PriceFeedFixture> {
const testAggregatorFactory = await ethers.getContractFactory("TestAggregatorV3")
const testAggregator = await testAggregatorFactory.deploy()

const chainlinkPriceFeedFactory = await ethers.getContractFactory("ChainlinkPriceFeedWithCachedTwap")
const chainlinkPriceFeedFactory = await ethers.getContractFactory("ChainlinkPriceFeedV2")
const chainlinkPriceFeed = (await chainlinkPriceFeedFactory.deploy(
testAggregator.address,
twapInterval,
)) as ChainlinkPriceFeedWithCachedTwap
)) as ChainlinkPriceFeedV2

return { bandPriceFeed, bandReference: testStdReference, baseAsset, chainlinkPriceFeed, aggregator: testAggregator }
}
Expand All @@ -50,7 +44,7 @@ describe.skip("Price feed gas test", () => {
const loadFixture: ReturnType<typeof waffle.createFixtureLoader> = waffle.createFixtureLoader([admin])
let bandPriceFeed: BandPriceFeed
let bandReference: TestStdReference
let chainlinkPriceFeed: ChainlinkPriceFeedWithCachedTwap
let chainlinkPriceFeed: ChainlinkPriceFeedV2
let aggregator: TestAggregatorV3
let currentTime: number
let testPriceFeed: TestPriceFeed
Expand Down

0 comments on commit f6ceba7

Please sign in to comment.