include all gains from staking/stability-pool when performing operations on them

This commit is contained in:
Edward Mulraney 2021-06-04 15:55:04 +01:00
parent 97db94fe59
commit 5be5cb6866
6 changed files with 240 additions and 89 deletions

View File

@ -31,12 +31,24 @@ contract Events {
event LogClaimCollateralFromRedemption(address indexed borrower, uint amount, uint setId); event LogClaimCollateralFromRedemption(address indexed borrower, uint amount, uint setId);
/* Stability Pool */ /* Stability Pool */
event LogStabilityDeposit(address indexed borrower, uint amount, address frontendTag, uint getId); event LogStabilityDeposit(
event LogStabilityWithdraw(address indexed borrower, uint amount, uint setId); address indexed borrower,
uint amount,
address frontendTag,
uint getDepositId,
uint setEthGainId,
uint setLqtyGainId
);
event LogStabilityWithdraw(address indexed borrower,
uint amount,
uint setWithdrawId,
uint setEthGainId,
uint setLqtyGainId
);
event LogStabilityMoveEthGainToTrove(address indexed borrower, uint amount); event LogStabilityMoveEthGainToTrove(address indexed borrower, uint amount);
/* Staking */ /* Staking */
event LogStake(address indexed borrower, uint amount, uint getId); event LogStake(address indexed borrower, uint amount, uint getStakeId, uint setEthGainId, uint setLusdGainId);
event LogUnstake(address indexed borrower, uint amount, uint setId); event LogUnstake(address indexed borrower, uint amount, uint setUnstakeId, uint setEthGainId, uint setLusdGainId);
event LogClaimStakingGains(address indexed borrower, uint ethAmount, uint lusdAmount); event LogClaimStakingGains(address indexed borrower, uint ethGain, uint lusdGain, uint setEthGainId, uint setLusdGainId);
} }

View File

@ -53,6 +53,7 @@ interface StabilityPoolLike {
function withdrawFromSP(uint _amount) external; function withdrawFromSP(uint _amount) external;
function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external; function withdrawETHGainToTrove(address _upperHint, address _lowerHint) external;
function getDepositorETHGain(address _depositor) external view returns (uint); function getDepositorETHGain(address _depositor) external view returns (uint);
function getDepositorLQTYGain(address _depositor) external view returns (uint);
} }
interface StakingLike { interface StakingLike {

View File

@ -276,36 +276,53 @@ abstract contract LiquityResolver is Events, Helpers {
* @notice Deposit LUSD into Stability Pool * @notice Deposit LUSD into Stability Pool
* @param amount Amount of LUSD to deposit into Stability Pool * @param amount Amount of LUSD to deposit into Stability Pool
* @param frontendTag Address of the frontend to make this deposit against (determines the kickback rate of rewards) * @param frontendTag Address of the frontend to make this deposit against (determines the kickback rate of rewards)
* @param getId Optional storage slot to retrieve the LUSD from * @param getDepositId Optional storage slot to retrieve the LUSD from
* @param setEthGainId Optional storage slot to store any ETH gains in
* @param setLqtyGainId Optional storage slot to store any ETH gains in
*/ */
function stabilityDeposit( function stabilityDeposit(
uint amount, uint amount,
address frontendTag, address frontendTag,
uint getId uint getDepositId,
uint setEthGainId,
uint setLqtyGainId
) external returns (string memory _eventName, bytes memory _eventParam) { ) external returns (string memory _eventName, bytes memory _eventParam) {
amount = getUint(getId, amount); amount = getUint(getDepositId, amount);
uint ethGain = stabilityPool.getDepositorETHGain(address(this));
stabilityPool.provideToSP(amount, frontendTag); uint lqtyGain = stabilityPool.getDepositorLQTYGain(address(this));
_eventName = "LogStabilityDeposit(address,uint256,address,uint256)"; stabilityPool.provideToSP(amount, frontendTag);
_eventParam = abi.encode(msg.sender, amount, frontendTag, getId); setUint(setEthGainId, ethGain);
setUint(setLqtyGainId, lqtyGain);
_eventName = "LogStabilityDeposit(address,uint256,address,uint256,uint256,uint256)";
_eventParam = abi.encode(msg.sender, amount, frontendTag, getDepositId, setEthGainId, setLqtyGainId);
} }
/** /**
* @dev Withdraw user deposited LUSD from Stability Pool * @dev Withdraw user deposited LUSD from Stability Pool
* @notice Withdraw LUSD from Stability Pool * @notice Withdraw LUSD from Stability Pool
* @param amount Amount of LUSD to withdraw from Stability Pool * @param amount Amount of LUSD to withdraw from Stability Pool
* @param setId Optional storage slot to store the withdrawn LUSD * @param setWithdrawId Optional storage slot to store the withdrawn LUSD
* @param setEthGainId Optional storage slot to store any ETH gains in
* @param setLqtyGainId Optional storage slot to store any ETH gains in
*/ */
function stabilityWithdraw( function stabilityWithdraw(
uint amount, uint amount,
uint setId uint setWithdrawId,
uint setEthGainId,
uint setLqtyGainId
) external returns (string memory _eventName, bytes memory _eventParam) { ) external returns (string memory _eventName, bytes memory _eventParam) {
stabilityPool.withdrawFromSP(amount); stabilityPool.withdrawFromSP(amount);
setUint(setId, amount); uint ethGain = stabilityPool.getDepositorETHGain(address(this));
uint lqtyGain = stabilityPool.getDepositorLQTYGain(address(this));
setUint(setWithdrawId, amount);
setUint(setEthGainId, ethGain);
setUint(setLqtyGainId, lqtyGain);
_eventName = "LogStabilityWithdraw(address,uint256,uint256)"; _eventName = "LogStabilityWithdraw(address,uint256,uint256,uint256,uint256)";
_eventParam = abi.encode(msg.sender, amount, setId); _eventParam = abi.encode(msg.sender, amount, setWithdrawId, setEthGainId, setLqtyGainId);
} }
/** /**
@ -331,32 +348,52 @@ abstract contract LiquityResolver is Events, Helpers {
* @dev Sends LQTY tokens from user to Staking Pool * @dev Sends LQTY tokens from user to Staking Pool
* @notice Stake LQTY in Staking Pool * @notice Stake LQTY in Staking Pool
* @param amount Amount of LQTY to stake * @param amount Amount of LQTY to stake
* @param getId Optional storage slot to retrieve the LQTY from * @param getStakeId Optional storage slot to retrieve the LQTY from
* @param setEthGainId Optional storage slot to store any ETH gains
* @param setLusdGainId Optional storage slot to store any LUSD gains
*/ */
function stake( function stake(
uint amount, uint amount,
uint getId uint getStakeId,
uint setEthGainId,
uint setLusdGainId
) external returns (string memory _eventName, bytes memory _eventParam) { ) external returns (string memory _eventName, bytes memory _eventParam) {
amount = getUint(getId, amount); uint ethGain = staking.getPendingETHGain(address(this));
uint lusdGain = staking.getPendingLUSDGain(address(this));
amount = getUint(getStakeId, amount);
staking.stake(amount); staking.stake(amount);
_eventName = "LogStake(address,uint256,uint256)"; setUint(setEthGainId, ethGain);
_eventParam = abi.encode(msg.sender, amount, getId); setUint(setLusdGainId, lusdGain);
_eventName = "LogStake(address,uint256,uint256,uint256,uint256)";
_eventParam = abi.encode(msg.sender, amount, getStakeId, setEthGainId, setLusdGainId);
} }
/** /**
* @dev Sends LQTY tokens from Staking Pool to user * @dev Sends LQTY tokens from Staking Pool to user
* @notice Unstake LQTY in Staking Pool * @notice Unstake LQTY in Staking Pool
* @param amount Amount of LQTY to unstake * @param amount Amount of LQTY to unstake
* @param setId Optional storage slot to store the unstaked LQTY * @param setStakeId Optional storage slot to store the unstaked LQTY
* @param setEthGainId Optional storage slot to store any ETH gains
* @param setLusdGainId Optional storage slot to store any LUSD gains
*/ */
function unstake( function unstake(
uint amount, uint amount,
uint setId uint setStakeId,
uint setEthGainId,
uint setLusdGainId
) external returns (string memory _eventName, bytes memory _eventParam) { ) external returns (string memory _eventName, bytes memory _eventParam) {
uint ethGain = staking.getPendingETHGain(address(this));
uint lusdGain = staking.getPendingLUSDGain(address(this));
staking.unstake(amount); staking.unstake(amount);
setUint(setId, amount); setUint(setStakeId, amount);
_eventName = "LogUnstake(address,uint256,uint256)"; setUint(setEthGainId, ethGain);
_eventParam = abi.encode(msg.sender, amount, setId); setUint(setLusdGainId, lusdGain);
_eventName = "LogUnstake(address,uint256,uint256,uint256,uint256)";
_eventParam = abi.encode(msg.sender, amount, setStakeId, setEthGainId, setLusdGainId);
} }
/** /**
@ -365,17 +402,20 @@ abstract contract LiquityResolver is Events, Helpers {
* @param setEthGainId Optional storage slot to store the claimed ETH * @param setEthGainId Optional storage slot to store the claimed ETH
* @param setLusdGainId Optional storage slot to store the claimed LUSD * @param setLusdGainId Optional storage slot to store the claimed LUSD
*/ */
function claimStakingGains(uint setEthGainId, uint setLusdGainId) external returns (string memory _eventName, bytes memory _eventParam) { function claimStakingGains(
uint ethAmount = staking.getPendingETHGain(address(this)); uint setEthGainId,
uint lusdAmount = staking.getPendingLUSDGain(address(this)); uint setLusdGainId
) external returns (string memory _eventName, bytes memory _eventParam) {
uint ethGain = staking.getPendingETHGain(address(this));
uint lusdGain = staking.getPendingLUSDGain(address(this));
// Gains are claimed when a user's stake is adjusted, so we unstake 0 to trigger the claim // Gains are claimed when a user's stake is adjusted, so we unstake 0 to trigger the claim
staking.unstake(0); staking.unstake(0);
setUint(setEthGainId, ethAmount); setUint(setEthGainId, ethGain);
setUint(setLusdGainId, lusdAmount); setUint(setLusdGainId, lusdGain);
_eventName = "LogClaimStakingGains(address,uint256,uint256)"; _eventName = "LogClaimStakingGains(address,uint256,uint256,uint256,uint256)";
_eventParam = abi.encode(msg.sender, ethAmount, lusdAmount); _eventParam = abi.encode(msg.sender, ethGain, lusdGain, setEthGainId, setLusdGainId);
} }
/* End: Staking */ /* End: Staking */

View File

@ -52,6 +52,8 @@ const STAKING_ADDRESS = "0x4f9Fbb3f1E99B56e0Fe2892e623Ed36A76Fc605d";
const STAKING_ABI = [ const STAKING_ABI = [
"function stake(uint _LQTYamount) external", "function stake(uint _LQTYamount) external",
"function unstake(uint _LQTYamount) external", "function unstake(uint _LQTYamount) external",
"function getPendingETHGain(address _user) external view returns (uint)",
"function getPendingLUSDGain(address _user) external view returns (uint)",
]; ];
const LQTY_TOKEN_ADDRESS = "0x6DEA81C8171D0bA574754EF6F8b412F2Ed88c54D"; const LQTY_TOKEN_ADDRESS = "0x6DEA81C8171D0bA574754EF6F8b412F2Ed88c54D";

View File

@ -327,8 +327,8 @@ const getRedemptionHints = async (
}; };
}; };
const redeem = async (amount, from, to, liquity) => { const redeem = async (amount, from, wallet, liquity) => {
await sendToken(liquity.lusdToken, amount, from, to); await sendToken(liquity.lusdToken, amount, from, wallet.address);
const { const {
partialRedemptionHintNicr, partialRedemptionHintNicr,
firstRedemptionHint, firstRedemptionHint,

View File

@ -1184,7 +1184,7 @@ describe.only("Liquity", () => {
}); });
}); });
describe("claim()", () => { describe("claimCollateralFromRedemption()", () => {
it("claims collateral from a redeemed Trove", async () => { it("claims collateral from a redeemed Trove", async () => {
// Create a low collateralized Trove // Create a low collateralized Trove
const depositAmount = ethers.utils.parseEther("1.5"); const depositAmount = ethers.utils.parseEther("1.5");
@ -1360,7 +1360,7 @@ describe.only("Liquity", () => {
const stabilityDepositSpell = { const stabilityDepositSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stabilityDeposit", method: "stabilityDeposit",
args: [amount, frontendTag, 0], args: [amount, frontendTag, 0, 0, 0],
}; };
const depositTx = await dsa const depositTx = await dsa
@ -1377,7 +1377,10 @@ describe.only("Liquity", () => {
it("returns Instadapp event name and data", async () => { it("returns Instadapp event name and data", async () => {
const amount = ethers.utils.parseUnits("100", 18); const amount = ethers.utils.parseUnits("100", 18);
const frontendTag = ethers.constants.AddressZero; const frontendTag = ethers.constants.AddressZero;
const getId = 0; const getDepositId = 0;
const setEthGainId = 0;
const setLqtyGainId = 0;
await helpers.sendToken( await helpers.sendToken(
liquity.lusdToken, liquity.lusdToken,
amount, amount,
@ -1388,7 +1391,7 @@ describe.only("Liquity", () => {
const stabilityDepositSpell = { const stabilityDepositSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stabilityDeposit", method: "stabilityDeposit",
args: [amount, frontendTag, getId], args: [amount, frontendTag, getDepositId, 0, 0],
}; };
const depositTx = await dsa const depositTx = await dsa
@ -1399,11 +1402,18 @@ describe.only("Liquity", () => {
const castLogEvent = receipt.events.find((e) => e.event === "LogCast") const castLogEvent = receipt.events.find((e) => e.event === "LogCast")
.args; .args;
const expectedEventParams = ethers.utils.defaultAbiCoder.encode( const expectedEventParams = ethers.utils.defaultAbiCoder.encode(
["address", "uint256", "address", "uint256"], ["address", "uint256", "address", "uint256", "uint256", "uint256"],
[wallet.address, amount, frontendTag, getId] [
wallet.address,
amount,
frontendTag,
getDepositId,
setEthGainId,
setLqtyGainId,
]
); );
expect(castLogEvent.eventNames[0]).eq( expect(castLogEvent.eventNames[0]).eq(
"LogStabilityDeposit(address,uint256,address,uint256)" "LogStabilityDeposit(address,uint256,address,uint256,uint256,uint256)"
); );
expect(castLogEvent.eventParams[0]).eq(expectedEventParams); expect(castLogEvent.eventParams[0]).eq(expectedEventParams);
}); });
@ -1435,14 +1445,14 @@ describe.only("Liquity", () => {
const stabilityDepositSpell = { const stabilityDepositSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stabilityDeposit", method: "stabilityDeposit",
args: [amount, frontendTag, 0], args: [amount, frontendTag, 0, 0, 0],
}; };
// Withdraw half of the deposit // Withdraw half of the deposit
const stabilitWithdrawSpell = { const stabilitWithdrawSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stabilityWithdraw", method: "stabilityWithdraw",
args: [amount.div(2), 0], args: [amount.div(2), 0, 0, 0],
}; };
const spells = [stabilityDepositSpell, stabilitWithdrawSpell]; const spells = [stabilityDepositSpell, stabilitWithdrawSpell];
@ -1475,7 +1485,6 @@ describe.only("Liquity", () => {
}); });
const amount = ethers.utils.parseUnits("100", 18); const amount = ethers.utils.parseUnits("100", 18);
const frontendTag = ethers.constants.AddressZero; const frontendTag = ethers.constants.AddressZero;
const setId = 0;
await helpers.sendToken( await helpers.sendToken(
liquity.lusdToken, liquity.lusdToken,
@ -1487,15 +1496,19 @@ describe.only("Liquity", () => {
const stabilityDepositSpell = { const stabilityDepositSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stabilityDeposit", method: "stabilityDeposit",
args: [amount, frontendTag, setId], args: [amount, frontendTag, 0, 0, 0],
}; };
// Withdraw half of the deposit // Withdraw half of the deposit
const withdrawAmount = amount.div(2); const withdrawAmount = amount.div(2);
const setWithdrawId = 0;
const setEthGainId = 0;
const setLqtyGainId = 0;
const stabilitWithdrawSpell = { const stabilitWithdrawSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stabilityWithdraw", method: "stabilityWithdraw",
args: [withdrawAmount, 0], args: [withdrawAmount, setWithdrawId, setEthGainId, setLqtyGainId],
}; };
const spells = [stabilityDepositSpell, stabilitWithdrawSpell]; const spells = [stabilityDepositSpell, stabilitWithdrawSpell];
@ -1507,11 +1520,17 @@ describe.only("Liquity", () => {
const castLogEvent = receipt.events.find((e) => e.event === "LogCast") const castLogEvent = receipt.events.find((e) => e.event === "LogCast")
.args; .args;
const expectedEventParams = ethers.utils.defaultAbiCoder.encode( const expectedEventParams = ethers.utils.defaultAbiCoder.encode(
["address", "uint256", "uint256"], ["address", "uint256", "uint256", "uint256", "uint256"],
[wallet.address, withdrawAmount, setId] [
wallet.address,
withdrawAmount,
setWithdrawId,
setEthGainId,
setLqtyGainId,
]
); );
expect(castLogEvent.eventNames[1]).eq( expect(castLogEvent.eventNames[1]).eq(
"LogStabilityWithdraw(address,uint256,uint256)" "LogStabilityWithdraw(address,uint256,uint256,uint256,uint256)"
); );
expect(castLogEvent.eventParams[1]).eq(expectedEventParams); expect(castLogEvent.eventParams[1]).eq(expectedEventParams);
}); });
@ -1544,7 +1563,7 @@ describe.only("Liquity", () => {
const stabilityDepositSpell = { const stabilityDepositSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stabilityDeposit", method: "stabilityDeposit",
args: [amount, frontendTag, 0], args: [amount, frontendTag, 0, 0, 0],
}; };
const depositTx = await dsa const depositTx = await dsa
@ -1605,7 +1624,7 @@ describe.only("Liquity", () => {
const stabilityDepositSpell = { const stabilityDepositSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stabilityDeposit", method: "stabilityDeposit",
args: [amount, frontendTag, 0], args: [amount, frontendTag, 0, 0, 0],
}; };
const depositTx = await dsa const depositTx = await dsa
@ -1670,7 +1689,7 @@ describe.only("Liquity", () => {
const stakeSpell = { const stakeSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stake", method: "stake",
args: [amount, 0], args: [amount, 0, 0, 0],
}; };
const stakeTx = await dsa const stakeTx = await dsa
@ -1698,12 +1717,14 @@ describe.only("Liquity", () => {
helpers.JUSTIN_SUN_ADDRESS, helpers.JUSTIN_SUN_ADDRESS,
dsa.address dsa.address
); );
const getId = 0;
const getStakeId = 0;
const setEthGainId = 0;
const setLusdGainId = 0;
const stakeSpell = { const stakeSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stake", method: "stake",
args: [amount, getId], args: [amount, getStakeId, setEthGainId, setLusdGainId],
}; };
const stakeTx = await dsa const stakeTx = await dsa
@ -1715,11 +1736,11 @@ describe.only("Liquity", () => {
const castLogEvent = receipt.events.find((e) => e.event === "LogCast") const castLogEvent = receipt.events.find((e) => e.event === "LogCast")
.args; .args;
const expectedEventParams = ethers.utils.defaultAbiCoder.encode( const expectedEventParams = ethers.utils.defaultAbiCoder.encode(
["address", "uint256", "uint256"], ["address", "uint256", "uint256", "uint256", "uint256"],
[wallet.address, amount, getId] [wallet.address, amount, getStakeId, setEthGainId, setLusdGainId]
); );
expect(castLogEvent.eventNames[0]).eq( expect(castLogEvent.eventNames[0]).eq(
"LogStake(address,uint256,uint256)" "LogStake(address,uint256,uint256,uint256,uint256)"
); );
expect(castLogEvent.eventParams[0]).eq(expectedEventParams); expect(castLogEvent.eventParams[0]).eq(expectedEventParams);
}); });
@ -1738,7 +1759,7 @@ describe.only("Liquity", () => {
const stakeSpell = { const stakeSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stake", method: "stake",
args: [amount, 0], args: [amount, 0, 0, 0],
}; };
const stakeTx = await dsa const stakeTx = await dsa
@ -1750,11 +1771,10 @@ describe.only("Liquity", () => {
const totalStakingBalanceBefore = await liquity.lqtyToken.balanceOf( const totalStakingBalanceBefore = await liquity.lqtyToken.balanceOf(
contracts.STAKING_ADDRESS contracts.STAKING_ADDRESS
); );
const unstakeSpell = { const unstakeSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "unstake", method: "unstake",
args: [amount, 0], args: [amount, 0, 0, 0],
}; };
const unstakeTx = await dsa const unstakeTx = await dsa
@ -1786,18 +1806,20 @@ describe.only("Liquity", () => {
const stakeSpell = { const stakeSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "stake", method: "stake",
args: [amount, 0], args: [amount, 0, 0, 0],
}; };
await dsa await dsa
.connect(wallet) .connect(wallet)
.cast(...encodeSpells([stakeSpell]), wallet.address); .cast(...encodeSpells([stakeSpell]), wallet.address);
const setId = 0; const setUnstakeId = 0;
const setEthGainId = 0;
const setLusdGainId = 0;
const unstakeSpell = { const unstakeSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "unstake", method: "unstake",
args: [amount, setId], args: [amount, setUnstakeId, setEthGainId, setLusdGainId],
}; };
const unstakeTx = await dsa const unstakeTx = await dsa
@ -1809,46 +1831,42 @@ describe.only("Liquity", () => {
const castLogEvent = receipt.events.find((e) => e.event === "LogCast") const castLogEvent = receipt.events.find((e) => e.event === "LogCast")
.args; .args;
const expectedEventParams = ethers.utils.defaultAbiCoder.encode( const expectedEventParams = ethers.utils.defaultAbiCoder.encode(
["address", "uint256", "uint256"], ["address", "uint256", "uint256", "uint256", "uint256"],
[wallet.address, amount, setId] [wallet.address, amount, setUnstakeId, setEthGainId, setLusdGainId]
); );
expect(castLogEvent.eventNames[0]).eq( expect(castLogEvent.eventNames[0]).eq(
"LogUnstake(address,uint256,uint256)" "LogUnstake(address,uint256,uint256,uint256,uint256)"
); );
expect(castLogEvent.eventParams[0]).eq(expectedEventParams); expect(castLogEvent.eventParams[0]).eq(expectedEventParams);
}); });
}); });
describe.skip("claimStakingGains()", () => { describe("claimStakingGains()", () => {
it("Claims gains from staking", async () => {}); it("Claims gains from staking", async () => {
it("returns Instadapp event name and data", async () => {
const stakerDsa = await buildDSAv2(wallet.address); const stakerDsa = await buildDSAv2(wallet.address);
const whaleLqtyBalance = await liquity.lqtyToken.balanceOf( const amount = ethers.utils.parseUnits("1000", 18); // 1000 LQTY
helpers.JUSTIN_SUN_ADDRESS
);
console.log("BALANCE", whaleLqtyBalance.toString());
// Stake lots of LQTY // Stake lots of LQTY
await helpers.sendToken( await helpers.sendToken(
liquity.lqtyToken, liquity.lqtyToken,
whaleLqtyBalance, amount,
helpers.JUSTIN_SUN_ADDRESS, helpers.JUSTIN_SUN_ADDRESS,
stakerDsa.address stakerDsa.address
); );
const dsaBalance = await liquity.lqtyToken.balanceOf( const stakeSpell = {
stakerDsa.address connector: helpers.CONNECTOR_NAME,
); method: "stake",
console.log("dsaBalance", dsaBalance.toString()); args: [amount, 0, 0, 0],
await liquity.staking };
.connect(stakerDsa.signer) await stakerDsa
.stake(ethers.utils.parseUnits("1", 18)); .connect(wallet)
.cast(...encodeSpells([stakeSpell]), wallet.address);
// Open a Trove to cause an ETH issuance gain for stakers // Open a Trove to cause an ETH issuance gain for stakers
await helpers.createDsaTrove( await helpers.createDsaTrove(
dsa, dsa,
wallet, wallet,
liqiuty.hintHelpers, liquity.hintHelpers,
liquity.sortedTroves liquity.sortedTroves
); );
@ -1856,18 +1874,96 @@ describe.only("Liquity", () => {
await helpers.redeem( await helpers.redeem(
ethers.utils.parseUnits("1000", 18), ethers.utils.parseUnits("1000", 18),
contracts.STABILITY_POOL_ADDRESS, contracts.STABILITY_POOL_ADDRESS,
wallet.address, wallet,
liquity liquity
); );
const setEthGainId = 0; const setEthGainId = 0;
const setLusdGainId = 0; const setLusdGainId = 0;
const ethGain = await liquity.staking.getPendingETHGain(
stakerDsa.address
);
const lusdGain = await liquity.staking.getPendingLUSDGain(
stakerDsa.address
);
const claimStakingGainsSpell = { const claimStakingGainsSpell = {
connector: helpers.CONNECTOR_NAME, connector: helpers.CONNECTOR_NAME,
method: "claimStakingGains", method: "claimStakingGains",
args: [setEthGainId, setLusdGainId], args: [setEthGainId, setLusdGainId],
}; };
const ethBalanceBefore = await ethers.provider.getBalance(
stakerDsa.address
);
// Claim gains
await stakerDsa
.connect(wallet)
.cast(...encodeSpells([claimStakingGainsSpell]), wallet.address);
const ethBalanceAfter = await ethers.provider.getBalance(
stakerDsa.address
);
const lusdBalanceAfter = await liquity.lusdToken.balanceOf(
stakerDsa.address
);
expect(ethBalanceAfter).to.eq(ethBalanceBefore.add(ethGain));
expect(lusdBalanceAfter).to.eq(lusdGain);
});
it("returns Instadapp event name and data", async () => {
const stakerDsa = await buildDSAv2(wallet.address);
const amount = ethers.utils.parseUnits("1000", 18); // 1000 LQTY
// Stake lots of LQTY
await helpers.sendToken(
liquity.lqtyToken,
amount,
helpers.JUSTIN_SUN_ADDRESS,
stakerDsa.address
);
const stakeSpell = {
connector: helpers.CONNECTOR_NAME,
method: "stake",
args: [amount, 0, 0, 0],
};
await stakerDsa
.connect(wallet)
.cast(...encodeSpells([stakeSpell]), wallet.address);
// Open a Trove to cause an ETH issuance gain for stakers
await helpers.createDsaTrove(
dsa,
wallet,
liquity.hintHelpers,
liquity.sortedTroves
);
// Redeem some ETH to cause an LUSD redemption gain for stakers
await helpers.redeem(
ethers.utils.parseUnits("1000", 18),
contracts.STABILITY_POOL_ADDRESS,
wallet,
liquity
);
const setEthGainId = 0;
const setLusdGainId = 0;
const ethGain = await liquity.staking.getPendingETHGain(
stakerDsa.address
);
const lusdGain = await liquity.staking.getPendingLUSDGain(
stakerDsa.address
);
const claimStakingGainsSpell = {
connector: helpers.CONNECTOR_NAME,
method: "claimStakingGains",
args: [setEthGainId, setLusdGainId],
};
// Claim gains
const claimGainsTx = await stakerDsa const claimGainsTx = await stakerDsa
.connect(wallet) .connect(wallet)
.cast(...encodeSpells([claimStakingGainsSpell]), wallet.address); .cast(...encodeSpells([claimStakingGainsSpell]), wallet.address);
@ -1877,11 +1973,11 @@ describe.only("Liquity", () => {
const castLogEvent = receipt.events.find((e) => e.event === "LogCast") const castLogEvent = receipt.events.find((e) => e.event === "LogCast")
.args; .args;
const expectedEventParams = ethers.utils.defaultAbiCoder.encode( const expectedEventParams = ethers.utils.defaultAbiCoder.encode(
["address", "uint256", "uint256"], ["address", "uint256", "uint256", "uint256", "uint256"],
[helpers.JUSTIN_SUN_ADDRESS, setEthGainId, setLusdGainId] [wallet.address, ethGain, lusdGain, setEthGainId, setLusdGainId]
); );
expect(castLogEvent.eventNames[0]).eq( expect(castLogEvent.eventNames[0]).eq(
"LogClaimStakingGains(address,uint256,uint256)" "LogClaimStakingGains(address,uint256,uint256,uint256,uint256)"
); );
expect(castLogEvent.eventParams[0]).eq(expectedEventParams); expect(castLogEvent.eventParams[0]).eq(expectedEventParams);
}); });