diff --git a/contracts/protocols/mainnet/liquity.sol b/contracts/protocols/mainnet/liquity.sol index fef0dc0..c22f149 100644 --- a/contracts/protocols/mainnet/liquity.sol +++ b/contracts/protocols/mainnet/liquity.sol @@ -20,14 +20,14 @@ interface StabilityPoolLike { function getDepositorLQTYGain(address _depositor) external view returns (uint); } -abstract contract StakingLike { - mapping(address => uint) public stakes; - function getPendingETHGain(address _user) external virtual view returns (uint); - function getPendingLUSDGain(address _user) external virtual view returns (uint); +interface StakingLike { + function stakes(address owner) external view returns (uint); + function getPendingETHGain(address _user) external view returns (uint); + function getPendingLUSDGain(address _user) external view returns (uint); } -abstract contract PriceFeedLike { - uint public lastGoodPrice; +interface PoolLike { + function getETH() external view returns (uint); } contract DSMath { @@ -46,12 +46,11 @@ contract Helpers is DSMath { StakingLike internal constant staking = StakingLike(0x4f9Fbb3f1E99B56e0Fe2892e623Ed36A76Fc605d); - PriceFeedLike internal constant priceFeed = - PriceFeedLike(0x4c517D4e2C851CA76d7eC94B805269Df0f2201De); + PoolLike internal constant activePool = + PoolLike(0xDf9Eb223bAFBE5c5271415C75aeCD68C21fE3D7F); - address constant activePoolAddress = 0xDf9Eb223bAFBE5c5271415C75aeCD68C21fE3D7F; - - address constant defaultPoolAddress = 0x896a3F03176f05CFbb4f006BfCd8723F2B0D741C; + PoolLike internal constant defaultPool = + PoolLike(0x896a3F03176f05CFbb4f006BfCd8723F2B0D741C); struct Trove { uint collateral; @@ -87,10 +86,9 @@ contract Helpers is DSMath { contract Resolver is Helpers { - function getTrove(address owner) public view returns (Trove memory) { - (uint debt, uint collateral, uint _, uint __) = troveManager.getEntireDebtAndColl(owner); - uint ethPrice = priceFeed.lastGoodPrice(); - uint icr = troveManager.getCurrentICR(owner, ethPrice); + function getTrove(address owner, uint oracleEthPrice) public view returns (Trove memory) { + (uint debt, uint collateral, , ) = troveManager.getEntireDebtAndColl(owner); + uint icr = troveManager.getCurrentICR(owner, oracleEthPrice); return Trove(collateral, debt, icr); } @@ -108,19 +106,18 @@ contract Resolver is Helpers { return Stake(amount, ethGain, lusdGain); } - function getPosition(address owner) external view returns (Position memory) { - Trove memory trove = getTrove(owner); + function getPosition(address owner, uint oracleEthPrice) external view returns (Position memory) { + Trove memory trove = getTrove(owner, oracleEthPrice); StabilityDeposit memory stability = getStabilityDeposit(owner); Stake memory stake = getStake(owner); 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 ethTvl = add(activePoolAddress.balance, defaultPoolAddress.balance); - uint ethPrice = priceFeed.lastGoodPrice(); - uint tcr = troveManager.getTCR(ethPrice); - bool isInRecoveryMode = troveManager.checkRecoveryMode(ethPrice); + uint ethTvl = add(activePool.getETH(), defaultPool.getETH()); + uint tcr = troveManager.getTCR(oracleEthPrice); + bool isInRecoveryMode = troveManager.checkRecoveryMode(oracleEthPrice); return System(borrowFee, ethTvl, tcr, isInRecoveryMode); } } diff --git a/test/liquity.js b/test/liquity.js index f0f85f0..b4a9170 100644 --- a/test/liquity.js +++ b/test/liquity.js @@ -8,11 +8,15 @@ const BLOCK_NUMBER = 12478959; // Liquity user with a Trove, Stability deposit, and Stake 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) */ const expectedTrovePosition = [ /* collateral */ BigNumber.from("582880000000000000000000"), /* debt */ BigNumber.from("372000200000000000000000000"), - /* icr */ BigNumber.from("3839454035181671407"), + /* icr */ BigNumber.from("3859882210893925325"), ]; const expectedStabilityPosition = [ /* deposit */ BigNumber.from("299979329615565997640451998"), @@ -28,22 +32,29 @@ const expectedStakePosition = [ const expectedSystemState = [ /* borrowFee */ BigNumber.from("6900285109012952"), /* ethTvl */ BigNumber.from("852500462432421494350957"), - /* tcr */ BigNumber.from("3232993993257432140"), + /* tcr */ BigNumber.from("3250195441371082828"), /* isInRecoveryMode */ false, ]; /* End: Mock test data */ describe("InstaLiquityResolver", () => { let liquity; + let liquityPriceOracle; before(async () => { 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" ); - 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(); }); @@ -53,7 +64,11 @@ describe("InstaLiquityResolver", () => { describe("getTrove()", () => { 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); }); }); @@ -76,7 +91,11 @@ describe("InstaLiquityResolver", () => { describe("getPosition()", () => { 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 = [ expectedTrovePosition, expectedStabilityPosition, @@ -88,7 +107,8 @@ describe("InstaLiquityResolver", () => { describe("getSystemState()", () => { 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); }); });