Skip to content
This repository has been archived by the owner on May 24, 2024. It is now read-only.

Risk Manager reference asset update #193

Open
wants to merge 1 commit into
base: permissioned-market-activation
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions contracts/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ abstract contract Constants {
uint8 internal constant DEFERLIQUIDITY__CLEAN = 1;
uint8 internal constant DEFERLIQUIDITY__DIRTY = 2;

// Fiat currency Reference Assets, as per ISO 4217
// https://en.wikipedia.org/wiki/ISO_4217
address internal constant REFERENCE_ASSET__USD = address(840);

// Pricing types

Expand Down
15 changes: 11 additions & 4 deletions contracts/modules/RiskManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ contract RiskManager is IRiskManager, BaseLogic {
}

price = uint(answer);

// if reference asset is USD, it implies that Chainlink asset/USD price feeds are used.
// Chainlink asset/USD price feeds are 8 decimals, so we need to scale them up to 18 decimals
if (referenceAsset == REFERENCE_ASSET__USD) price = price * 1e10;

if (price > 1e36) price = 1e36;
}

Expand Down Expand Up @@ -147,20 +152,22 @@ contract RiskManager is IRiskManager, BaseLogic {
twap = 1e18;
twapPeriod = twapWindow;
} else if (pricingType == PRICINGTYPE__UNISWAP3_TWAP) {
(twap, twapPeriod) = callUniswapObserve(underlying, pricingParameters, twapWindow, underlyingDecimalsScaler);
if (uniswapFactory != address(0)) {
(twap, twapPeriod) = callUniswapObserve(underlying, pricingParameters, twapWindow, underlyingDecimalsScaler);
}
} else if (pricingType == PRICINGTYPE__CHAINLINK) {
twap = callChainlinkLatestAnswer(chainlinkPriceFeedLookup[underlying]);
twapPeriod = 0;

// if price invalid and uniswap fallback pool configured get the price from uniswap
if (twap == 0 && uint24(pricingParameters) != 0) {
if (twap == 0 && uint24(pricingParameters) != 0 && uniswapFactory != address(0)) {
(twap, twapPeriod) = callUniswapObserve(underlying, pricingParameters, twapWindow, underlyingDecimalsScaler);
}

require(twap != 0, "e/unable-to-get-the-price");
} else {
revert("e/unknown-pricing-type");
}

require(twap != 0, "e/unable-to-get-the-price");
}

function getPrice(address underlying) external view override returns (uint twap, uint twapPeriod) {
Expand Down
83 changes: 83 additions & 0 deletions test/chainlinkPriceFeed.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,87 @@ et.testSet({
],
})

.test({
desc: "chainlink price scaling when USD is the reference asset",
actions: ctx => [
{ action: 'cb', cb: async () => {

// Install RiskManager with the USD as the reference asset
const riskManagerSettings = {
referenceAsset: et.ethers.utils.hexZeroPad(et.BN(840).toHexString(), 20),
uniswapFactory: ethers.constants.AddressZero,
uniswapPoolInitCodeHash: et.ethers.utils.hexZeroPad('0x', 32),
}

ctx.contracts.modules.riskManager = await (await ctx.factories.RiskManager.deploy(
et.ethers.utils.hexZeroPad('0x', 32),
riskManagerSettings
)).deployed()

await (await ctx.contracts.installer.connect(ctx.wallet)
.installModules([ctx.contracts.modules.riskManager.address])).wait();
}},

// Set up the price feed

{ send: 'governance.setChainlinkPriceFeed', args:
[ctx.contracts.tokens.TST.address, ctx.contracts.AggregatorTST.address], onLogs: logs => {
et.expect(logs.length).to.equal(1);
et.expect(logs[0].name).to.equal('GovSetChainlinkPriceFeed');
et.expect(logs[0].args.underlying).to.equal(ctx.contracts.tokens.TST.address);
et.expect(logs[0].args.chainlinkAggregator).to.equal(ctx.contracts.AggregatorTST.address);
}},

// Set pool pricing configuration

{ send: 'governance.setPricingConfig', args: [ctx.contracts.tokens.TST.address, PRICINGTYPE__CHAINLINK, et.DefaultUniswapFee], onLogs: logs => {
et.expect(logs.length).to.equal(1);
et.expect(logs[0].name).to.equal('GovSetPricingConfig');
et.expect(logs[0].args.underlying).to.equal(ctx.contracts.tokens.TST.address);
et.expect(logs[0].args.newPricingType).to.equal(PRICINGTYPE__CHAINLINK);
et.expect(logs[0].args.newPricingParameter).to.equal(et.DefaultUniswapFee);
}},

// test getPrice

{ action: 'cb', cb: async () => {
await ctx.contracts.AggregatorTST.mockSetData([1, et.ethers.utils.parseUnits('1', 8), 0, 0, 0]);
const resultTST = await ctx.contracts.exec.getPrice(ctx.contracts.tokens.TST.address);
et.expect(resultTST.twap).to.equal(et.ethers.utils.parseUnits('1', 18));
et.expect(resultTST.twapPeriod).to.equal(0);
}},

// test getPriceFull

{ action: 'cb', cb: async () => {
// Set up the price equal to the max price of 1e36

await ctx.contracts.AggregatorTST.mockSetData([1, et.ethers.utils.parseUnits('1', 8), 0, 0, 0]);
const resultTST = await ctx.contracts.exec.getPriceFull(ctx.contracts.tokens.TST.address);
et.expect(resultTST.twap).to.equal(et.ethers.utils.parseUnits('1', 18));
et.expect(resultTST.currPrice).to.equal(resultTST.twap);
et.expect(resultTST.twapPeriod).to.equal(0);
}},

// test getPrice

{ action: 'cb', cb: async () => {
await ctx.contracts.AggregatorTST.mockSetData([1, et.ethers.utils.parseUnits('1.2345', 8), 0, 0, 0]);
const resultTST = await ctx.contracts.exec.getPrice(ctx.contracts.tokens.TST.address);
et.expect(resultTST.twap).to.equal(et.ethers.utils.parseUnits('1.2345', 18));
et.expect(resultTST.twapPeriod).to.equal(0);
}},

// test getPriceFull

{ action: 'cb', cb: async () => {
await ctx.contracts.AggregatorTST.mockSetData([1, et.ethers.utils.parseUnits('1.2345', 8), 0, 0, 0]);
const resultTST = await ctx.contracts.exec.getPriceFull(ctx.contracts.tokens.TST.address);
et.expect(resultTST.twap).to.equal(et.ethers.utils.parseUnits('1.2345', 18));
et.expect(resultTST.currPrice).to.equal(resultTST.twap);
et.expect(resultTST.twapPeriod).to.equal(0);
}}
],
})

.run();
23 changes: 23 additions & 0 deletions test/twap.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,30 @@ et.testSet({
})


.test({
desc: "no uniswap configured",
actions: ctx => [
{ action: 'cb', cb: async () => {
// Install RiskManager without uniswap configured
const riskManagerSettings = {
referenceAsset: ctx.contracts.tokens['WETH'].address,
uniswapFactory: ethers.constants.AddressZero,
uniswapPoolInitCodeHash: et.ethers.utils.hexZeroPad('0x', 32),
}

ctx.contracts.modules.riskManager = await (await ctx.factories.RiskManager.deploy(
et.ethers.utils.hexZeroPad('0x', 32),
riskManagerSettings
)).deployed()

await (await ctx.contracts.installer.connect(ctx.wallet)
.installModules([ctx.contracts.modules.riskManager.address])).wait();
}},

{ action: 'getPrice', underlying: 'TST', expectError: 'e/unable-to-get-the-price', },
{ action: 'getPrice', underlying: 'TST2', expectError: 'e/unable-to-get-the-price', },
],
})


.run();