Merge pull request #4 from liquity/add-oracle-eth-price-to-responses

Handle ETH price fetched internally rather than passed in
This commit is contained in:
Edward Mulraney 2021-07-15 12:02:29 -04:00 committed by GitHub
commit aaee3fc291
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 34 deletions

View File

@ -109,6 +109,7 @@ contract Helpers is Math {
uint collateral; uint collateral;
uint debt; uint debt;
uint icr; uint icr;
uint oracleEthPrice;
} }
struct StabilityDeposit { struct StabilityDeposit {
@ -134,21 +135,35 @@ contract Helpers is Math {
uint ethTvl; uint ethTvl;
uint tcr; uint tcr;
bool isInRecoveryMode; bool isInRecoveryMode;
uint oracleEthPrice;
}
struct TrovePositionHints {
address upperHint;
address lowerHint;
}
struct RedemptionPositionHints {
uint partialHintNicr;
address firstHint;
address upperHint;
address lowerHint;
uint oracleEthPrice;
} }
} }
contract Resolver is Helpers { contract Resolver is Helpers {
function fetchETHPrice() public returns (uint) { function fetchEthPrice() public returns (uint) {
return priceFeedOracle.fetchPrice(); return priceFeedOracle.fetchPrice();
} }
function getTrove(address owner) public returns (Trove memory) { function getTrove(address owner) public returns (Trove memory) {
uint oracleEthPrice = fetchETHPrice(); uint oracleEthPrice = fetchEthPrice();
(uint debt, uint collateral, , ) = troveManager.getEntireDebtAndColl(owner); (uint debt, uint collateral, , ) = troveManager.getEntireDebtAndColl(owner);
uint icr = troveManager.getCurrentICR(owner, oracleEthPrice); uint icr = troveManager.getCurrentICR(owner, oracleEthPrice);
return Trove(collateral, debt, icr); return Trove(collateral, debt, icr, oracleEthPrice);
} }
function getStabilityDeposit(address owner) public view returns (StabilityDeposit memory) { function getStabilityDeposit(address owner) public view returns (StabilityDeposit memory) {
@ -173,40 +188,37 @@ contract Resolver is Helpers {
} }
function getSystemState() external returns (System memory) { function getSystemState() external returns (System memory) {
uint oracleEthPrice = fetchETHPrice(); uint oracleEthPrice = fetchEthPrice();
uint borrowFee = troveManager.getBorrowingRateWithDecay(); uint borrowFee = troveManager.getBorrowingRateWithDecay();
uint ethTvl = add(activePool.getETH(), defaultPool.getETH()); uint ethTvl = add(activePool.getETH(), defaultPool.getETH());
uint tcr = troveManager.getTCR(oracleEthPrice); uint tcr = troveManager.getTCR(oracleEthPrice);
bool isInRecoveryMode = troveManager.checkRecoveryMode(oracleEthPrice); bool isInRecoveryMode = troveManager.checkRecoveryMode(oracleEthPrice);
return System(borrowFee, ethTvl, tcr, isInRecoveryMode); return System(borrowFee, ethTvl, tcr, isInRecoveryMode, oracleEthPrice);
} }
function getTrovePositionHints(uint collateral, uint debt, uint searchIterations, uint randomSeed) external view returns ( function getTrovePositionHints(uint collateral, uint debt, uint searchIterations, uint randomSeed) external view returns (
address upperHint, TrovePositionHints memory
address lowerHint
) { ) {
// See: https://github.com/liquity/dev#supplying-hints-to-trove-operations // See: https://github.com/liquity/dev#supplying-hints-to-trove-operations
uint nominalCr = hintHelpers.computeNominalCR(collateral, debt); uint nominalCr = hintHelpers.computeNominalCR(collateral, debt);
searchIterations = searchIterations == 0 ? mul(10, sqrt(sortedTroves.getSize())) : searchIterations; searchIterations = searchIterations == 0 ? mul(10, sqrt(sortedTroves.getSize())) : searchIterations;
randomSeed = randomSeed == 0 ? block.number : randomSeed; randomSeed = randomSeed == 0 ? block.number : randomSeed;
(address hintAddress, ,) = hintHelpers.getApproxHint(nominalCr, searchIterations, randomSeed); (address hintAddress, ,) = hintHelpers.getApproxHint(nominalCr, searchIterations, randomSeed);
return sortedTroves.findInsertPosition(nominalCr, hintAddress, hintAddress); (address upperHint, address lowerHint) = sortedTroves.findInsertPosition(nominalCr, hintAddress, hintAddress);
return TrovePositionHints(upperHint, lowerHint);
} }
function getRedemptionPositionHints(uint amount, uint searchIterations, uint randomSeed) external returns ( function getRedemptionPositionHints(uint amount, uint searchIterations, uint randomSeed) external returns (
RedemptionPositionHints memory
uint partialHintNicr,
address firstHint,
address upperHint,
address lowerHint
) { ) {
uint oracleEthPrice = fetchETHPrice(); uint oracleEthPrice = fetchEthPrice();
// See: https://github.com/liquity/dev#hints-for-redeemcollateral // See: https://github.com/liquity/dev#hints-for-redeemcollateral
(firstHint, partialHintNicr, ) = hintHelpers.getRedemptionHints(amount, oracleEthPrice, 0); (address firstHint, uint partialHintNicr, ) = hintHelpers.getRedemptionHints(amount, oracleEthPrice, 0);
searchIterations = searchIterations == 0 ? mul(10, sqrt(sortedTroves.getSize())) : searchIterations; searchIterations = searchIterations == 0 ? mul(10, sqrt(sortedTroves.getSize())) : searchIterations;
randomSeed = randomSeed == 0 ? block.number : randomSeed; randomSeed = randomSeed == 0 ? block.number : randomSeed;
(address hintAddress, ,) = hintHelpers.getApproxHint(partialHintNicr, searchIterations, randomSeed); (address hintAddress, ,) = hintHelpers.getApproxHint(partialHintNicr, searchIterations, randomSeed);
(upperHint, lowerHint) = sortedTroves.findInsertPosition(partialHintNicr, hintAddress, hintAddress); (address upperHint, address lowerHint) = sortedTroves.findInsertPosition(partialHintNicr, hintAddress, hintAddress);
return RedemptionPositionHints(partialHintNicr, firstHint, upperHint, lowerHint, oracleEthPrice);
} }
} }

View File

@ -18,6 +18,7 @@ const expectedTrovePosition = {
collateral: BigNumber.from("582880000000000000000000"), collateral: BigNumber.from("582880000000000000000000"),
debt: BigNumber.from("372000200000000000000000000"), debt: BigNumber.from("372000200000000000000000000"),
icr: BigNumber.from("3859882210893925325"), icr: BigNumber.from("3859882210893925325"),
oracleEthPrice: BigNumber.from("2463417777980000000000"),
}; };
const expectedStabilityPosition = { const expectedStabilityPosition = {
deposit: BigNumber.from("299979329615565997640451998"), deposit: BigNumber.from("299979329615565997640451998"),
@ -34,6 +35,7 @@ const expectedSystemState = {
ethTvl: BigNumber.from("852500462432421494350957"), ethTvl: BigNumber.from("852500462432421494350957"),
tcr: BigNumber.from("3250195441371082828"), tcr: BigNumber.from("3250195441371082828"),
isInRecoveryMode: false, isInRecoveryMode: false,
oracleEthPrice: BigNumber.from("2463417777980000000000"),
}; };
const expectedTrovePositionHints = { const expectedTrovePositionHints = {
upperHint: "0xbf9a4eCC4151f28C03100bA2C0555a3D3e439e69", upperHint: "0xbf9a4eCC4151f28C03100bA2C0555a3D3e439e69",
@ -44,6 +46,7 @@ const expectedRedemptionPositionHints = {
firstHint: "0xc16aDd8bA17ab81B27e930Da8a67848120565d8c", firstHint: "0xc16aDd8bA17ab81B27e930Da8a67848120565d8c",
upperHint: "0x66882C005188F0F4d95825ED7A7F78ed3055f167", upperHint: "0x66882C005188F0F4d95825ED7A7F78ed3055f167",
lowerHint: "0x0C22C11a8ed4C23ffD19629283548B1692b58e92", lowerHint: "0x0C22C11a8ed4C23ffD19629283548B1692b58e92",
oracleEthPrice: BigNumber.from("2463417777980000000000"),
}; };
/* End: Mock test data */ /* End: Mock test data */
@ -75,22 +78,23 @@ describe("InstaLiquityResolver", () => {
describe("getTrove()", () => { describe("getTrove()", () => {
it("returns a user's Trove position", async () => { it("returns a user's Trove position", async () => {
const oracleEthPrice = await liquityPriceOracle.callStatic.fetchPrice(); const trovePosition = await liquity.callStatic.getTrove(
const trovePosition = await liquity.getTrove( JUSTIN_SUN_ADDRESS
JUSTIN_SUN_ADDRESS,
oracleEthPrice
); );
expect(trovePosition.collateral).to.equal( expect(trovePosition.collateral).to.equal(
expectedTrovePosition.collateral expectedTrovePosition.collateral
); );
expect(trovePosition.debt).to.equal(expectedTrovePosition.debt); expect(trovePosition.debt).to.equal(expectedTrovePosition.debt);
expect(trovePosition.icr).to.equal(expectedTrovePosition.icr); expect(trovePosition.icr).to.equal(expectedTrovePosition.icr);
expect(trovePosition.oracleEthPrice).to.equal(
expectedTrovePosition.oracleEthPrice
);
}); });
}); });
describe("getStabilityDeposit()", () => { describe("getStabilityDeposit()", () => {
it("returns a user's Stability Pool position", async () => { it("returns a user's Stability Pool position", async () => {
const stabilityPosition = await liquity.getStabilityDeposit( const stabilityPosition = await liquity.callStatic.getStabilityDeposit(
JUSTIN_SUN_ADDRESS JUSTIN_SUN_ADDRESS
); );
expect(stabilityPosition.deposit).to.equal( expect(stabilityPosition.deposit).to.equal(
@ -107,7 +111,9 @@ describe("InstaLiquityResolver", () => {
describe("getStake()", () => { describe("getStake()", () => {
it("returns a user's Stake position", async () => { it("returns a user's Stake position", async () => {
const stakePosition = await liquity.getStake(JUSTIN_SUN_ADDRESS); const stakePosition = await liquity.callStatic.getStake(
JUSTIN_SUN_ADDRESS
);
expect(stakePosition.amount).to.equal(expectedStakePosition.amount); expect(stakePosition.amount).to.equal(expectedStakePosition.amount);
expect(stakePosition.ethGain).to.equal(expectedStakePosition.ethGain); expect(stakePosition.ethGain).to.equal(expectedStakePosition.ethGain);
expect(stakePosition.lusdGain).to.equal(expectedStakePosition.lusdGain); expect(stakePosition.lusdGain).to.equal(expectedStakePosition.lusdGain);
@ -116,11 +122,7 @@ describe("InstaLiquityResolver", () => {
describe("getPosition()", () => { describe("getPosition()", () => {
it("returns a user's Liquity position", async () => { it("returns a user's Liquity position", async () => {
const oracleEthPrice = await liquityPriceOracle.callStatic.fetchPrice(); const position = await liquity.callStatic.getPosition(JUSTIN_SUN_ADDRESS);
const position = await liquity.getPosition(
JUSTIN_SUN_ADDRESS,
oracleEthPrice
);
const expectedPosition = { const expectedPosition = {
trove: expectedTrovePosition, trove: expectedTrovePosition,
stability: expectedStabilityPosition, stability: expectedStabilityPosition,
@ -150,14 +152,16 @@ describe("InstaLiquityResolver", () => {
describe("getSystemState()", () => { describe("getSystemState()", () => {
it("returns Liquity system state", async () => { it("returns Liquity system state", async () => {
const oracleEthPrice = await liquityPriceOracle.callStatic.fetchPrice(); const systemState = await liquity.callStatic.getSystemState();
const systemState = await liquity.getSystemState(oracleEthPrice);
expect(systemState.borrowFee).to.equal(expectedSystemState.borrowFee); expect(systemState.borrowFee).to.equal(expectedSystemState.borrowFee);
expect(systemState.ethTvl).to.equal(expectedSystemState.ethTvl); expect(systemState.ethTvl).to.equal(expectedSystemState.ethTvl);
expect(systemState.tcr).to.equal(expectedSystemState.tcr); expect(systemState.tcr).to.equal(expectedSystemState.tcr);
expect(systemState.isInRecoveryMode).to.equal( expect(systemState.isInRecoveryMode).to.equal(
expectedSystemState.isInRecoveryMode expectedSystemState.isInRecoveryMode
); );
expect(systemState.oracleEthPrice).to.equal(
expectedSystemState.oracleEthPrice
);
}); });
}); });
@ -167,7 +171,10 @@ describe("InstaLiquityResolver", () => {
const debt = hre.ethers.utils.parseUnits("5000", 18); // 5,000 LUSD const debt = hre.ethers.utils.parseUnits("5000", 18); // 5,000 LUSD
const searchIterations = 10; const searchIterations = 10;
const randomSeed = 3; const randomSeed = 3;
const [upperHint, lowerHint] = await liquity.getTrovePositionHints( const [
upperHint,
lowerHint,
] = await liquity.callStatic.getTrovePositionHints(
collateral, collateral,
debt, debt,
searchIterations, searchIterations,
@ -182,7 +189,6 @@ describe("InstaLiquityResolver", () => {
describe("getRedemptionPositionHints()", () => { describe("getRedemptionPositionHints()", () => {
it("returns the upper and lower address of the range of Troves to be redeemed against the given amount", async () => { it("returns the upper and lower address of the range of Troves to be redeemed against the given amount", async () => {
const amount = hre.ethers.utils.parseUnits("10000", 18); // 10,000 LUSD const amount = hre.ethers.utils.parseUnits("10000", 18); // 10,000 LUSD
const oracleEthPrice = await liquityPriceOracle.callStatic.fetchPrice();
const searchIterations = 10; const searchIterations = 10;
const randomSeed = 3; const randomSeed = 3;
const [ const [
@ -190,9 +196,9 @@ describe("InstaLiquityResolver", () => {
firstHint, firstHint,
upperHint, upperHint,
lowerHint, lowerHint,
] = await liquity.getRedemptionPositionHints(
amount,
oracleEthPrice, oracleEthPrice,
] = await liquity.callStatic.getRedemptionPositionHints(
amount,
searchIterations, searchIterations,
randomSeed randomSeed
); );
@ -203,6 +209,7 @@ describe("InstaLiquityResolver", () => {
expect(firstHint).eq(expectedRedemptionPositionHints.firstHint); expect(firstHint).eq(expectedRedemptionPositionHints.firstHint);
expect(upperHint).eq(expectedRedemptionPositionHints.upperHint); expect(upperHint).eq(expectedRedemptionPositionHints.upperHint);
expect(lowerHint).eq(expectedRedemptionPositionHints.lowerHint); expect(lowerHint).eq(expectedRedemptionPositionHints.lowerHint);
expect(oracleEthPrice).eq(expectedRedemptionPositionHints.oracleEthPrice);
}); });
}); });
}); });