Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions config/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type BaseTokenConfig = {
oracleType?: string;
dataStreamFeedId?: string;
dataStreamFeedDecimals?: number;
dataStreamInverted?: boolean;
dataStreamSpreadReductionFactor?: BigNumberish;
priceFeed?: OraclePriceFeed;
};
Expand Down
1 change: 1 addition & 0 deletions contracts/config/Config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@ contract Config is ReentrancyGuard, RoleModule, BasicMulticall {
allowedBaseKeys[Keys.BUYBACK_MAX_PRICE_IMPACT_FACTOR] = true;
allowedBaseKeys[Keys.BUYBACK_MAX_PRICE_AGE] = true;

allowedBaseKeys[Keys.DATA_STREAM_INVERTED] = true;
allowedBaseKeys[Keys.DATA_STREAM_SPREAD_REDUCTION_FACTOR] = true;
}

Expand Down
12 changes: 12 additions & 0 deletions contracts/data/Keys.sol
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,8 @@ library Keys {
bytes32 public constant PRICE_FEED_HEARTBEAT_DURATION = keccak256(abi.encode("PRICE_FEED_HEARTBEAT_DURATION"));
// @dev key for data stream feed id
bytes32 public constant DATA_STREAM_ID = keccak256(abi.encode("DATA_STREAM_ID"));
// @dev key for data stream inverted flag (e.g. USD/JPY for JPY)
bytes32 public constant DATA_STREAM_INVERTED = keccak256(abi.encode("DATA_STREAM_INVERTED"));
// @dev key for data stream feed multiplier
bytes32 public constant DATA_STREAM_MULTIPLIER = keccak256(abi.encode("DATA_STREAM_MULTIPLIER"));
bytes32 public constant DATA_STREAM_SPREAD_REDUCTION_FACTOR = keccak256(abi.encode("DATA_STREAM_SPREAD_REDUCTION_FACTOR"));
Expand Down Expand Up @@ -1855,6 +1857,16 @@ library Keys {
));
}

// @dev key for data stream inverted flag (e.g. USD/JPY for JPY)
// @param token the token to get the key for
// @return key for data stream inverted flag
function dataStreamInvertedKey(address token) internal pure returns (bytes32) {
return keccak256(abi.encode(
DATA_STREAM_INVERTED,
token
));
}

// @dev key for data stream feed multiplier
// @param token the token to get the key for
// @return key for data stream feed multiplier
Expand Down
7 changes: 7 additions & 0 deletions contracts/oracle/ChainlinkDataStreamProvider.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ contract ChainlinkDataStreamProvider is IOracleProvider {
uint256 adjustedBidPrice = Precision.mulDiv(uint256(uint192(report.bid)), precision, Precision.FLOAT_PRECISION);
uint256 adjustedAskPrice = Precision.mulDiv(uint256(uint192(report.ask)), precision, Precision.FLOAT_PRECISION);

bool inverted = dataStore.getBool(Keys.dataStreamInvertedKey(token));
if (inverted) {
uint256 temp = adjustedBidPrice;
adjustedBidPrice = Precision.mulDiv(Precision.FLOAT_PRECISION, Precision.FLOAT_PRECISION, adjustedAskPrice);
adjustedAskPrice = Precision.mulDiv(Precision.FLOAT_PRECISION, Precision.FLOAT_PRECISION, temp);
}

uint256 spreadReductionFactor = _getDataStreamSpreadReductionFactor(token);
if (spreadReductionFactor != 0) {
// small optimization for full reduction
Expand Down
10 changes: 9 additions & 1 deletion deploy/configureDataStreamFeeds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { HardhatRuntimeEnvironment } from "hardhat/types";
import { TokenConfig } from "../config/tokens";

import * as keys from "../utils/keys";
import { setBytes32IfDifferent, setUintIfDifferent } from "../utils/dataStore";
import { setBoolIfDifferent, setBytes32IfDifferent, setUintIfDifferent } from "../utils/dataStore";
import { expandDecimals } from "../utils/math";

const func = async ({ gmx }: HardhatRuntimeEnvironment) => {
Expand Down Expand Up @@ -32,6 +32,14 @@ const func = async ({ gmx }: HardhatRuntimeEnvironment) => {
`data stream feed id for ${tokenSymbol} ${token.address}`
);

if (token.dataStreamInverted) {
await setBoolIfDifferent(
keys.dataStreamInvertedKey(token.address),
token.dataStreamInverted,
`data stream feed inverted flag for ${tokenSymbol} ${token.address}`
);
}

const dataStreamMultiplier = expandDecimals(1, 60 - token.decimals - token.dataStreamFeedDecimals);
await setUintIfDifferent(
keys.dataStreamMultiplierKey(token.address),
Expand Down
5 changes: 5 additions & 0 deletions utils/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export const PRICE_FEED = hashString("PRICE_FEED");
export const PRICE_FEED_MULTIPLIER = hashString("PRICE_FEED_MULTIPLIER");
export const PRICE_FEED_HEARTBEAT_DURATION = hashString("PRICE_FEED_HEARTBEAT_DURATION");
export const DATA_STREAM_ID = hashString("DATA_STREAM_ID");
export const DATA_STREAM_INVERTED = hashString("DATA_STREAM_INVERTED");
export const DATA_STREAM_MULTIPLIER = hashString("DATA_STREAM_MULTIPLIER");
export const DATA_STREAM_SPREAD_REDUCTION_FACTOR = hashString("DATA_STREAM_SPREAD_REDUCTION_FACTOR");
export const STABLE_PRICE = hashString("STABLE_PRICE");
Expand Down Expand Up @@ -402,6 +403,10 @@ export function dataStreamIdKey(token: string) {
return hashData(["bytes32", "address"], [DATA_STREAM_ID, token]);
}

export function dataStreamInvertedKey(token: string) {
return hashData(["bytes32", "address"], [DATA_STREAM_INVERTED, token]);
}

export function dataStreamMultiplierKey(token: string) {
return hashData(["bytes32", "address"], [DATA_STREAM_MULTIPLIER, token]);
}
Expand Down