add liquity resolver. fix flusher syntax error

This commit is contained in:
Edward Mulraney 2021-06-10 17:16:24 +01:00
parent db43810077
commit a67cea2fcf
4 changed files with 199 additions and 3 deletions

View File

@ -28,7 +28,7 @@ contract Resolver {
tokensBal[i] = Balances({
flusher: flushers[i],
balance: bals,
isDeployed: isContractDeployed(flushers[i]);
isDeployed: isContractDeployed(flushers[i])
});
}
return tokensBal;
@ -46,4 +46,4 @@ contract Resolver {
contract InstaFlusherERC20Resolver is Resolver {
string public constant name = "ERC20-Flusher-Resolver-v1";
}
}

View File

@ -0,0 +1,101 @@
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
interface TroveManagerLike {
function getCurrentICR(address _borrower, uint _price) external view returns (uint);
function getEntireDebtAndColl(address _borrower) external view returns (
uint debt,
uint coll,
uint pendingLUSDDebtReward,
uint pendingETHReward
);
}
interface StabilityPoolLike {
function getCompoundedLUSDDeposit(address _depositor) external view returns (uint);
function getDepositorETHGain(address _depositor) external view returns (uint);
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);
}
abstract contract PriceFeedLike {
uint public lastGoodPrice;
}
contract Helpers {
TroveManagerLike internal constant troveManager =
TroveManagerLike(0xA39739EF8b0231DbFA0DcdA07d7e29faAbCf4bb2);
StabilityPoolLike internal constant stabilityPool =
StabilityPoolLike(0x66017D22b0f8556afDd19FC67041899Eb65a21bb);
StakingLike internal constant staking =
StakingLike(0x4f9Fbb3f1E99B56e0Fe2892e623Ed36A76Fc605d);
PriceFeedLike internal constant priceFeed =
PriceFeedLike(0x4c517D4e2C851CA76d7eC94B805269Df0f2201De);
struct Trove {
uint collateral;
uint debt;
uint icr;
}
struct StabilityDeposit {
uint deposit;
uint ethGain;
uint lqtyGain;
}
struct Stake {
uint amount;
uint ethGain;
uint lusdGain;
}
struct Position {
Trove trove;
StabilityDeposit stability;
Stake stake;
}
}
contract Resolver is Helpers {
function getTrove(address owner) public view returns (Trove memory) {
(uint debt, uint collateral, uint _, uint __) = troveManager.getEntireDebtAndColl(owner);
uint price = priceFeed.lastGoodPrice();
uint icr = troveManager.getCurrentICR(owner, price);
return Trove(collateral, debt, icr);
}
function getStabilityDeposit(address owner) public view returns (StabilityDeposit memory) {
uint deposit = stabilityPool.getCompoundedLUSDDeposit(owner);
uint ethGain = stabilityPool.getDepositorETHGain(owner);
uint lqtyGain = stabilityPool.getDepositorLQTYGain(owner);
return StabilityDeposit(deposit, ethGain, lqtyGain);
}
function getStake(address owner) public view returns (Stake memory) {
uint amount = staking.stakes(owner);
uint ethGain = staking.getPendingETHGain(owner);
uint lusdGain = staking.getPendingLUSDGain(owner);
return Stake(amount, ethGain, lusdGain);
}
function getPosition(address owner) external view returns (Position memory) {
Trove memory trove = getTrove(owner);
StabilityDeposit memory stability = getStabilityDeposit(owner);
Stake memory stake = getStake(owner);
return Position(trove, stability, stake);
}
}
contract InstaLiquityResolver is Resolver {
string public constant name = "Liquity-Resolver-v1";
}

View File

@ -4,7 +4,7 @@
"description": "The smart contracts which simplifies read operations.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "hardhat test"
},
"repository": {
"type": "git",

95
test/liquity.js Normal file
View File

@ -0,0 +1,95 @@
const { expect } = require("chai");
const hardhatConfig = require("../hardhat.config");
const { BigNumber } = hre.ethers;
// Deterministic block number to run these tests from on forked mainnet. If you change this, tests will break.
const BLOCK_NUMBER = 12478959;
// Liquity user with a Trove, Stability deposit, and Stake
const JUSTIN_SUN_ADDRESS = "0x903d12bf2c57a29f32365917c706ce0e1a84cce3";
/* 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"),
];
const expectedStabilityPosition = [
/* deposit */ BigNumber.from("299979329615565997640451998"),
/* ethGain */ BigNumber.from("8629038660000000000"),
/* lqtyGain */ BigNumber.from("53244322633874479119945"),
];
const expectedStakePosition = [
/* amount */ BigNumber.from("981562996504090969804965"),
/* ethGain */ BigNumber.from("18910541408996344243"),
/* lusdGain */ BigNumber.from("66201062534511228032281"),
];
/* End: Mock test data */
describe("InstaLiquityResolver", () => {
let liquity;
before(async () => {
await resetHardhatBlockNumber(BLOCK_NUMBER); // Start tests from clean mainnet fork at BLOCK_NUMBER
const LiquityFactory = await hre.ethers.getContractFactory(
"InstaLiquityResolver"
);
liquity = await LiquityFactory.deploy();
await liquity.deployed();
});
it("deploys the resolver", () => {
expect(liquity.address).to.exist;
});
describe("getTrove()", () => {
it("returns a user's Trove position", async () => {
const trovePosition = await liquity.getTrove(JUSTIN_SUN_ADDRESS);
expect(trovePosition).to.eql(expectedTrovePosition);
});
});
describe("getStabilityDeposit()", () => {
it("returns a user's Stability Pool position", async () => {
const stabilityPosition = await liquity.getStabilityDeposit(
JUSTIN_SUN_ADDRESS
);
expect(stabilityPosition).to.eql(expectedStabilityPosition);
});
});
describe("getStake()", () => {
it("returns a user's Stake position", async () => {
const stakePosition = await liquity.getStake(JUSTIN_SUN_ADDRESS);
expect(stakePosition).to.eql(expectedStakePosition);
});
});
describe("getPosition()", () => {
it("returns a user's Liquity position", async () => {
const position = await liquity.getPosition(JUSTIN_SUN_ADDRESS);
const expectedPosition = [
expectedTrovePosition,
expectedStabilityPosition,
expectedStakePosition,
];
expect(position).to.eql(expectedPosition);
});
});
});
const resetHardhatBlockNumber = async (blockNumber) => {
return await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
jsonRpcUrl: hardhatConfig.networks.hardhat.forking.url,
blockNumber,
},
},
],
});
};