Skip to content

Commit

Permalink
fix: handle frxETH depeg scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
web3rover committed Feb 27, 2024
1 parent 7ba3858 commit 58e01aa
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 14 deletions.
4 changes: 3 additions & 1 deletion contracts/oracles/EtherFiOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ contract EtherFiOracle is OracleInterface {
uint256 eETHAmount = asset == address(eETH) ? EXP_SCALE : weETH.getEETHByWeETH(EXP_SCALE);

// Calculate price of 1 eETH scaled by 1e18
uint256 eETHUSDPrice = RESILIENT_ORACLE.getPrice(ASSUME_EETH_ETH_EQUIVALENCE ? NATIVE_TOKEN_ADDR : address(eETH));
uint256 eETHUSDPrice = RESILIENT_ORACLE.getPrice(
ASSUME_EETH_ETH_EQUIVALENCE ? NATIVE_TOKEN_ADDR : address(eETH)
);

// eETH amount (for 1 weETH or eETH) * usdPrice (of eETH) / 1e18
return (eETHAmount * eETHUSDPrice) / EXP_SCALE;
Expand Down
23 changes: 21 additions & 2 deletions contracts/oracles/FraxOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import { EXP_SCALE } from "@venusprotocol/solidity-utilities/contracts/constants
* @notice This oracle fetches the price of sFrax and sfrxETH assets
*/
contract FraxOracle is OracleInterface {
/// @notice A flag assuming 1:1 price equivalence between frxETH/ETH
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
bool public immutable ASSUME_FRXETH_ETH_EQUIVALENCE;

/// @notice Address of sfraxETH
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
ISfraxETH public immutable sfraxETH;
Expand All @@ -25,6 +29,10 @@ contract FraxOracle is OracleInterface {
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
ISFrax public immutable sFRAX;

/// @notice Address of fraxETH
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
address public immutable fraxETH;

/// @notice Address of Resilient Oracle
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable
OracleInterface public immutable RESILIENT_ORACLE;
Expand All @@ -34,17 +42,28 @@ contract FraxOracle is OracleInterface {

/// @notice Constructor for the implementation contract.
/// @custom:oz-upgrades-unsafe-allow constructor
constructor(address _frax, address _sFrax, address _eth, address _sfraxETH, address _resilientOracleAddress) {
constructor(
address _frax,
address _sFrax,
address _eth,
address _sfraxETH,
address _fraxETH,
address _resilientOracleAddress,
bool _assumeEquivalence
) {
ensureNonzeroAddress(_frax);
ensureNonzeroAddress(_sFrax);
ensureNonzeroAddress(_eth);
ensureNonzeroAddress(_sfraxETH);
ensureNonzeroAddress(_fraxETH);
ensureNonzeroAddress(_resilientOracleAddress);
FRAX = _frax;
sFRAX = ISFrax(_sFrax);
ETH = _eth;
sfraxETH = ISfraxETH(_sfraxETH);
fraxETH = _fraxETH;
RESILIENT_ORACLE = OracleInterface(_resilientOracleAddress);
ASSUME_FRXETH_ETH_EQUIVALENCE = _assumeEquivalence;
}

/**
Expand All @@ -59,7 +78,7 @@ contract FraxOracle is OracleInterface {
if (asset == address(sFRAX)) {
assetPriceInUSD = RESILIENT_ORACLE.getPrice(FRAX);
} else {
assetPriceInUSD = RESILIENT_ORACLE.getPrice(ETH);
assetPriceInUSD = RESILIENT_ORACLE.getPrice(ASSUME_FRXETH_ETH_EQUIVALENCE ? ETH : address(fraxETH));
}

// get FRAX or ETH amount for 1 sFrax or sfraxETH scaled by 1e18
Expand Down
1 change: 1 addition & 0 deletions helpers/deploymentConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export const ADDRESSES: PreconfiguredAddresses = {
sFRAX: "0xA663B02CF0a4b149d2aD41910CB81e23e1c41c32",
sfraxETH: "0xac3e018457b222d93114458476f3e3416abbe38f",
FRAX: "0x853d955aCEf822Db058eb8505911ED77F175b99e",
fraxETH: "0x5e8422345238f34275888049021821e8e08caa1f",
weETH: "0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee",
eETH: "0x35fA164735182de50811E8e2E824cFb9B6118ac2",
},
Expand Down
5 changes: 3 additions & 2 deletions test/EtherFiOracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ describe("EtherFiOracle unit tests", () => {

describe("deployment", () => {
it("revert if weETH address is 0", async () => {
await expect(EtherFiOracleFactory.deploy(addr0000, eETHMock.address, resilientOracleMock.address, true)).to.be.reverted;
await expect(EtherFiOracleFactory.deploy(addr0000, eETHMock.address, resilientOracleMock.address, true)).to.be
.reverted;
});
it("revert if eETH address is 0", async () => {
await expect(EtherFiOracleFactory.deploy(weETHMock.address, addr0000, resilientOracleMock.address, true)).to.be
Expand All @@ -51,7 +52,7 @@ describe("EtherFiOracle unit tests", () => {
weETHMock.address,
eETHMock.address,
resilientOracleMock.address,
true
true,
);
});
});
Expand Down
57 changes: 48 additions & 9 deletions test/FraxOracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { addr0000 } from "./utils/data";
const { expect } = chai;
chai.use(smock.matchers);

const { FRAX, sFRAX, sfraxETH } = ADDRESSES.ethereum;
const { FRAX, sFRAX, sfraxETH, fraxETH } = ADDRESSES.ethereum;
const WETH = assets.ethereum.find(asset => asset.token === "WETH")?.address;
const FRAX_USD_PRICE = parseUnits("0.9979", 18); // 0.99 USD for 1 FRAX
const ETH_USD_PRICE = parseUnits("3100", 18); // 3100 USD for 1 ETH
Expand All @@ -33,36 +33,75 @@ describe("FraxOracle unit tests", () => {
sFraxETHMock.convertToAssets.returns(parseUnits("1.076546447254363344", 18));

FraxOracleFactory = await ethers.getContractFactory("FraxOracle");

console.log(FRAX, sFRAX, WETH, sfraxETH);
});

describe("deployment", () => {
it("revert if FRAX address is 0", async () => {
await expect(
FraxOracleFactory.deploy(addr0000, sFraxMock.address, WETH, sFraxETHMock.address, resilientOracleMock.address),
FraxOracleFactory.deploy(
addr0000,
sFraxMock.address,
WETH,
sFraxETHMock.address,
fraxETH,
resilientOracleMock.address,
true,
),
).to.be.reverted;
});
it("revert if sFRAX address is 0", async () => {
await expect(FraxOracleFactory.deploy(FRAX, addr0000, WETH, sFraxETHMock.address, resilientOracleMock.address)).to
.be.reverted;
await expect(
FraxOracleFactory.deploy(
FRAX,
addr0000,
WETH,
sFraxETHMock.address,
fraxETH,
resilientOracleMock.address,
true,
),
).to.be.reverted;
});
it("revert if ETH address is 0", async () => {
await expect(
FraxOracleFactory.deploy(FRAX, sFraxMock.address, addr0000, sFraxETHMock.address, resilientOracleMock.address),
FraxOracleFactory.deploy(
FRAX,
sFraxMock.address,
addr0000,
sFraxETHMock.address,
fraxETH,
resilientOracleMock.address,
true,
),
).to.be.reverted;
});
it("revert if sfraxETH address is 0", async () => {
await expect(FraxOracleFactory.deploy(FRAX, sFraxMock.address, WETH, addr0000, resilientOracleMock.address)).to.be
.reverted;
await expect(
FraxOracleFactory.deploy(FRAX, sFraxMock.address, WETH, addr0000, fraxETH, resilientOracleMock.address, true),
).to.be.reverted;
});
it("revert if sfraxETH address is 0", async () => {
await expect(
FraxOracleFactory.deploy(
FRAX,
sFraxMock.address,
WETH,
sFraxETHMock.address,
addr0000,
resilientOracleMock.address,
true,
),
).to.be.reverted;
});
it("should deploy contract", async () => {
FraxOracle = await FraxOracleFactory.deploy(
FRAX,
sFraxMock.address,
WETH,
sFraxETHMock.address,
fraxETH,
resilientOracleMock.address,
true,
);
});
});
Expand Down

0 comments on commit 58e01aa

Please sign in to comment.