pass oracle price into resolver as a parameter since it can't be queried on chain

This commit is contained in:
Edward Mulraney 2021-06-14 10:01:18 +01:00
parent dc108bf052
commit 34b7c39025
2 changed files with 46 additions and 29 deletions

View File

@ -20,14 +20,14 @@ interface StabilityPoolLike {
function getDepositorLQTYGain(address _depositor) external view returns (uint); function getDepositorLQTYGain(address _depositor) external view returns (uint);
} }
abstract contract StakingLike { interface StakingLike {
mapping(address => uint) public stakes; function stakes(address owner) external view returns (uint);
function getPendingETHGain(address _user) external virtual view returns (uint); function getPendingETHGain(address _user) external view returns (uint);
function getPendingLUSDGain(address _user) external virtual view returns (uint); function getPendingLUSDGain(address _user) external view returns (uint);
} }
abstract contract PriceFeedLike { interface PoolLike {
uint public lastGoodPrice; function getETH() external view returns (uint);
} }
contract DSMath { contract DSMath {
@ -46,12 +46,11 @@ contract Helpers is DSMath {
StakingLike internal constant staking = StakingLike internal constant staking =
StakingLike(0x4f9Fbb3f1E99B56e0Fe2892e623Ed36A76Fc605d); StakingLike(0x4f9Fbb3f1E99B56e0Fe2892e623Ed36A76Fc605d);
PriceFeedLike internal constant priceFeed = PoolLike internal constant activePool =
PriceFeedLike(0x4c517D4e2C851CA76d7eC94B805269Df0f2201De); PoolLike(0xDf9Eb223bAFBE5c5271415C75aeCD68C21fE3D7F);
address constant activePoolAddress = 0xDf9Eb223bAFBE5c5271415C75aeCD68C21fE3D7F; PoolLike internal constant defaultPool =
PoolLike(0x896a3F03176f05CFbb4f006BfCd8723F2B0D741C);
address constant defaultPoolAddress = 0x896a3F03176f05CFbb4f006BfCd8723F2B0D741C;
struct Trove { struct Trove {
uint collateral; uint collateral;
@ -87,10 +86,9 @@ contract Helpers is DSMath {
contract Resolver is Helpers { contract Resolver is Helpers {
function getTrove(address owner) public view returns (Trove memory) { function getTrove(address owner, uint oracleEthPrice) public view returns (Trove memory) {
(uint debt, uint collateral, uint _, uint __) = troveManager.getEntireDebtAndColl(owner); (uint debt, uint collateral, , ) = troveManager.getEntireDebtAndColl(owner);
uint ethPrice = priceFeed.lastGoodPrice(); uint icr = troveManager.getCurrentICR(owner, oracleEthPrice);
uint icr = troveManager.getCurrentICR(owner, ethPrice);
return Trove(collateral, debt, icr); return Trove(collateral, debt, icr);
} }
@ -108,19 +106,18 @@ contract Resolver is Helpers {
return Stake(amount, ethGain, lusdGain); return Stake(amount, ethGain, lusdGain);
} }
function getPosition(address owner) external view returns (Position memory) { function getPosition(address owner, uint oracleEthPrice) external view returns (Position memory) {
Trove memory trove = getTrove(owner); Trove memory trove = getTrove(owner, oracleEthPrice);
StabilityDeposit memory stability = getStabilityDeposit(owner); StabilityDeposit memory stability = getStabilityDeposit(owner);
Stake memory stake = getStake(owner); Stake memory stake = getStake(owner);
return Position(trove, stability, stake); return Position(trove, stability, stake);
} }
function getSystemState() external view returns (System memory) { function getSystemState(uint oracleEthPrice) external view returns (System memory) {
uint borrowFee = troveManager.getBorrowingRateWithDecay(); uint borrowFee = troveManager.getBorrowingRateWithDecay();
uint ethTvl = add(activePoolAddress.balance, defaultPoolAddress.balance); uint ethTvl = add(activePool.getETH(), defaultPool.getETH());
uint ethPrice = priceFeed.lastGoodPrice(); uint tcr = troveManager.getTCR(oracleEthPrice);
uint tcr = troveManager.getTCR(ethPrice); bool isInRecoveryMode = troveManager.checkRecoveryMode(oracleEthPrice);
bool isInRecoveryMode = troveManager.checkRecoveryMode(ethPrice);
return System(borrowFee, ethTvl, tcr, isInRecoveryMode); return System(borrowFee, ethTvl, tcr, isInRecoveryMode);
} }
} }

View File

@ -8,11 +8,15 @@ const BLOCK_NUMBER = 12478959;
// Liquity user with a Trove, Stability deposit, and Stake // Liquity user with a Trove, Stability deposit, and Stake
const JUSTIN_SUN_ADDRESS = "0x903d12bf2c57a29f32365917c706ce0e1a84cce3"; const JUSTIN_SUN_ADDRESS = "0x903d12bf2c57a29f32365917c706ce0e1a84cce3";
// Liquity price oracle
const PRICE_FEED_ADDRESS = "0x4c517D4e2C851CA76d7eC94B805269Df0f2201De";
const PRICE_FEED_ABI = ["function fetchPrice() external returns (uint)"];
/* Begin: Mock test data (based on specified BLOCK_NUMBER and JUSTIN_SUN_ADDRESS) */ /* Begin: Mock test data (based on specified BLOCK_NUMBER and JUSTIN_SUN_ADDRESS) */
const expectedTrovePosition = [ const expectedTrovePosition = [
/* collateral */ BigNumber.from("582880000000000000000000"), /* collateral */ BigNumber.from("582880000000000000000000"),
/* debt */ BigNumber.from("372000200000000000000000000"), /* debt */ BigNumber.from("372000200000000000000000000"),
/* icr */ BigNumber.from("3839454035181671407"), /* icr */ BigNumber.from("3859882210893925325"),
]; ];
const expectedStabilityPosition = [ const expectedStabilityPosition = [
/* deposit */ BigNumber.from("299979329615565997640451998"), /* deposit */ BigNumber.from("299979329615565997640451998"),
@ -28,22 +32,29 @@ const expectedStakePosition = [
const expectedSystemState = [ const expectedSystemState = [
/* borrowFee */ BigNumber.from("6900285109012952"), /* borrowFee */ BigNumber.from("6900285109012952"),
/* ethTvl */ BigNumber.from("852500462432421494350957"), /* ethTvl */ BigNumber.from("852500462432421494350957"),
/* tcr */ BigNumber.from("3232993993257432140"), /* tcr */ BigNumber.from("3250195441371082828"),
/* isInRecoveryMode */ false, /* isInRecoveryMode */ false,
]; ];
/* End: Mock test data */ /* End: Mock test data */
describe("InstaLiquityResolver", () => { describe("InstaLiquityResolver", () => {
let liquity; let liquity;
let liquityPriceOracle;
before(async () => { before(async () => {
await resetHardhatBlockNumber(BLOCK_NUMBER); // Start tests from clean mainnet fork at BLOCK_NUMBER await resetHardhatBlockNumber(BLOCK_NUMBER); // Start tests from clean mainnet fork at BLOCK_NUMBER
const LiquityFactory = await hre.ethers.getContractFactory( const liquityFactory = await hre.ethers.getContractFactory(
"InstaLiquityResolver" "InstaLiquityResolver"
); );
liquity = await LiquityFactory.deploy(); liquityPriceOracle = new hre.ethers.Contract(
PRICE_FEED_ADDRESS,
PRICE_FEED_ABI,
hre.ethers.provider
);
liquity = await liquityFactory.deploy();
await liquity.deployed(); await liquity.deployed();
}); });
@ -53,7 +64,11 @@ describe("InstaLiquityResolver", () => {
describe("getTrove()", () => { describe("getTrove()", () => {
it("returns a user's Trove position", async () => { it("returns a user's Trove position", async () => {
const trovePosition = await liquity.getTrove(JUSTIN_SUN_ADDRESS); const oracleEthPrice = await liquityPriceOracle.callStatic.fetchPrice();
const trovePosition = await liquity.getTrove(
JUSTIN_SUN_ADDRESS,
oracleEthPrice
);
expect(trovePosition).to.eql(expectedTrovePosition); expect(trovePosition).to.eql(expectedTrovePosition);
}); });
}); });
@ -76,7 +91,11 @@ describe("InstaLiquityResolver", () => {
describe("getPosition()", () => { describe("getPosition()", () => {
it("returns a user's Liquity position", async () => { it("returns a user's Liquity position", async () => {
const position = await liquity.getPosition(JUSTIN_SUN_ADDRESS); const oracleEthPrice = await liquityPriceOracle.callStatic.fetchPrice();
const position = await liquity.getPosition(
JUSTIN_SUN_ADDRESS,
oracleEthPrice
);
const expectedPosition = [ const expectedPosition = [
expectedTrovePosition, expectedTrovePosition,
expectedStabilityPosition, expectedStabilityPosition,
@ -88,7 +107,8 @@ describe("InstaLiquityResolver", () => {
describe("getSystemState()", () => { describe("getSystemState()", () => {
it("returns Liquity system state", async () => { it("returns Liquity system state", async () => {
const systemState = await liquity.getSystemState(); const oracleEthPrice = await liquityPriceOracle.callStatic.fetchPrice();
const systemState = await liquity.getSystemState(oracleEthPrice);
expect(systemState).to.eql(expectedSystemState); expect(systemState).to.eql(expectedSystemState);
}); });
}); });