8000 Steth fix rewards by lxzrv · Pull Request #76 · lidofinance/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Steth fix rewards #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions contracts/0.4.24/DePool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -524,19 +524,22 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp {
*/
function distributeRewards(uint256 _totalRewards) internal {
// Amount of the rewards in Ether
uint256 rewardsToDistribute = _totalRewards.mul(_getFee()).div(10000);
uint256 tokens2mint = _totalRewards.mul(_getFee()).div(10000);

assert(0 != getToken().totalSupply());

(uint16 treasuryFeeBasisPoints, uint16 insuranceFeeBasisPoints, ) = _getFeeDistribution();
uint256 toTreasury = rewardsToDistribute.mul(treasuryFeeBasisPoints).div(10000);
uint256 toInsuranceFund = rewardsToDistribute.mul(insuranceFeeBasisPoints).div(10000);
uint256 toSP = rewardsToDistribute.sub(toTreasury).sub(toInsuranceFund);
//FixMe: zero feeBasePoint breaks mint
uint256 toTreasury = tokens2mint.mul(treasuryFeeBasisPoints).div(10000);
uint256 toInsuranceFund = tokens2mint.mul(insuranceFeeBasisPoints).div(10000);
uint256 toSP = tokens2mint.sub(toTreasury).sub(toInsuranceFund);

getToken().mint(getTreasury(), toTreasury);
getToken().mint(getInsuranceFund(), toInsuranceFund);
getToken().mint(address(getSPs()), toSP);
getSPs().distributeRewards(address(getToken()), toSP);
getSPs().distributeRewards(
address(getToken()),
getToken().balanceOf(address(getSPs()))
);
}


Expand Down Expand Up @@ -657,7 +660,7 @@ contract DePool is IDePool, IsContract, Pausable, AragonApp {
uint256 remote = REMOTE_ETHER2_VALUE_POSITION.getStorageUint256();
// Until the oracle provides data, we assume that all staked ether is intact.
uint256 deposited = DEPOSITED_ETHER_VALUE_POSITION.getStorageUint256();
uint256 assets = _getBufferedEther().add(_hasOracleData() ? remote : deposited);
uint256 assets = _getBufferedEther().add(_hasOracleData() ? remote : deposited);

return assets;
}
Expand Down
16 changes: 7 additions & 9 deletions contracts/0.4.24/StETH.sol
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ contract StETH is ISTETH, Pausable, AragonApp {
* @param value The amount to be transferred.
*/
function _transfer(address from, address to, uint256 value) internal {
require(value != 0);
require(to != address(0));
uint256 sharesToTransfer = getSharesByPooledEth(value);
require(sharesToTransfer <= _shares[from]);
Expand Down Expand Up @@ -250,18 +249,17 @@ contract StETH is ISTETH, Pausable, AragonApp {
}

/**
* @notice Mint is called by dePool contract when user submits the ETH1.0 deposit.
* It calculates share difference to preserve ratio of shares to the increased
* amount of pooledEthers so that all the previously created shares still correspond
* to the same amount of pooled ethers.
* @notice Mint is called by dePool contract when user submits the ETH1.0 deposit.
* It calculates share difference to preserve ratio of shares to the increased
* amount of pooledEthers so that all the previously created shares still correspond
* to the same amount of pooled ethers.
* Then adds the calculated difference to the user's share and to the totalShares
* similarly as traditional mint() function does with balances.
* @param _to Receiver of new shares
* @param _value Amount of pooledEthers (then gets converted to shares)
*/
function mint(address _to, uint256 _value) external whenNotStopped authP(MINT_ROLE, arr(_to, _value)) {
require(_to != 0);
require(_value != 0);
uint256 sharesDifference;
uint256 totalControlledEthBefore = dePool.getTotalControlledEther();
if ( totalControlledEthBefore == 0) {
Expand Down Expand Up @@ -338,18 +336,18 @@ contract StETH is ISTETH, Pausable, AragonApp {

/**
* @dev Return the amount of shares backed by given amount of pooled Eth
* @param _pooledEthAmount The amount of pooled Eth
* @param _pooledEthAmount The amount of pooled Eth
*/
function getSharesByPooledEth(uint256 _pooledEthAmount) public view returns (uint256) {
if (dePool.getTotalControlledEther() == 0) {
return 0;
}
return _totalShares.mul(_pooledEthAmount).div(dePool.getTotalControlledEther());
return _pooledEthAmount.mul(_totalShares).div(dePool.getTotalControlledEther());
}

/**
* @dev Return the sum of the shares of all holders for better external visibility
*/
*/
function getTotalShares() public view returns (uint256) {
return _totalShares;
}
Expand Down
2 changes: 2 additions & 0 deletions contracts/0.4.24/interfaces/ISTETH.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ interface ISTETH /* is IERC20 */ {
* @param _value Amount of tokens to burn
*/
function burn(address _account, uint256 _value) external;

function balanceOf(address owner) external view returns (uint256);
}
4 changes: 1 addition & 3 deletions contracts/0.4.24/sps/StakingProvidersRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,7 @@ contract StakingProvidersRegistry is IStakingProvidersRegistry, IsContract, Arag

effectiveStake = sp.usedSigningKeys.sub(sp.stoppedValidators);
uint256 reward = uint256(effectiveStake).mul(_totalReward).div(uint256(effectiveStakeTotal));
//FixMe: in integration test with StETH the next line reverts without a reason
//require(IERC20(_token).transfer(sp.rewardAddress, reward), "TRANSFER_FAILED");
// leaves some dust on the balance of this
require(IERC20(_token).transfer(sp.rewardAddress, reward), "TRANSFER_FAILED");
}
}

Expand Down
34 changes: 15 additions & 19 deletions test/0.4.24/depool.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,9 @@ contract('DePool', ([appManager, voting, user1, user2, user3, nobody]) => {
token.balanceOf(ADDRESS_1), token.balanceOf(ADDRESS_2), token.balanceOf(ADDRESS_3), token.balanceOf(ADDRESS_4)
]);

/* FixMe
assertBn(div15(treasury_b), treasury, 'treasury token balance check');
assertBn(div15(insurance_b), insurance, 'insurance fund token balance check');
assertBn(div15(sps_b.add(a1).add(a2).add(a3).add(a4)), sp, 'staking providers token balance check');
*/
};

it('setFee works', async () => {
Expand Down Expand Up @@ -377,9 +375,9 @@ contract('DePool', ([appManager, voting, user1, user2, user3, nobody]) => {

await oracle.reportEther2(50, ETH(100)); // stale data
await checkStat({deposited: ETH(32), remote: ETH(30)});
//FixMe: fails with revert.
//await oracle.reportEther2(200, ETH(33));
//await checkStat({deposited: ETH(32), remote: ETH(33)});

await oracle.reportEther2(200, ETH(33));
await checkStat({deposited: ETH(32), remote: ETH(33)});
});

it('oracle data affects deposits', async () => {
Expand Down Expand Up @@ -415,18 +413,17 @@ contract('DePool', ([appManager, voting, user1, user2, user3, nobody]) => {
assertBn(await validatorRegistration.totalCalls(), 1);
assertBn(await app.getTotalControlledEther(), ETH(19));
assertBn(await app.getBufferedEther(), ETH(4));
//FixMe assertBn(await token.balanceOf(user1), tokens(2));
//FixMe assertBn(await token.totalSupply(), tokens(38));
assertBn(await token.balanceOf(user1), tokens(2));
assertBn(await token.totalSupply(), tokens(19));

// up
/*FixMe
await oracle.reportEther2(200, ETH(72));

await checkStat({deposited: ETH(32), remote: ETH(72)});
assertBn(await validatorRegistration.totalCalls(), 1);
assertBn(await app.getTotalControlledEther(), ETH(76));
assertBn(await app.getBufferedEther(), ETH(4));
assertBn(await token.totalSupply(), tokens(38));
assertBn(await token.totalSupply(), tokens(76));

// 2nd deposit, ratio is 2
await web3.eth.sendTransaction({to: app.address, from: user3, value: ETH(2)});
Expand All @@ -435,10 +432,9 @@ contract('DePool', ([appManager, voting, user1, user2, user3, nobody]) => {
assertBn(await validatorRegistration.totalCalls(), 1);
assertBn(await app.getTotalControlledEther(), ETH(78));
assertBn(await app.getBufferedEther(), ETH(6));
assertBn(await token.balanceOf(user1), tokens(4));
assertBn(await token.balanceOf(user3), tokens(1));
assertBn(await token.totalSupply(), tokens(39));
*/
assertBn(await token.balanceOf(user1), tokens(8));
assertBn(await token.balanceOf(user3), tokens(2));
assertBn(await token.totalSupply(), tokens(78));
});

it('can stop and resume', async () => {
Expand Down Expand Up @@ -489,8 +485,8 @@ contract('DePool', ([appManager, voting, user1, user2, user3, nobody]) => {

await oracle.reportEther2(300, ETH(36));
await checkStat({deposited: ETH(32), remote: ETH(36)});
//Fixme: assertBn(div15(await token.totalSupply()), 35888);
await checkRewards({treasury: 566, insurance: 377, sp: 944});
assertBn(await token.totalSupply(), tokens(38)); // remote + buffered
await checkRewards({treasury: 569, insurance: 385, sp: 974});
});

it('rewards distribution works', async () => {
Expand Down Expand Up @@ -524,8 +520,8 @@ contract('DePool', ([appManager, voting, user1, user2, user3, nobody]) => {
// now some rewards are here
await oracle.reportEther2(300, ETH(36));
await checkStat({deposited: ETH(32), remote: ETH(36)});
//Fixme assertBn(div15(await token.totalSupply()), 35888);
await checkRewards({treasury: 566, insurance: 377, sp: 944});
assertBn(await token.totalSupply(), tokens(38));
await checkRewards({treasury: 569, insurance: 385, sp: 974});
});

it('deposits accounted properly during rewards distribution', async () => {
Expand All @@ -545,8 +541,8 @@ contract('DePool', ([appManager, voting, user1, user2, user3, nobody]) => {

await oracle.reportEther2(300, ETH(36));
await checkStat({deposited: ETH(32), remote: ETH(36)});
//assertBn(div15(await token.totalSupply()), 65939);
await checkRewards({treasury: 581, insurance: 387, sp: 969});
assertBn(await token.totalSupply(), tokens(68));
await checkRewards({treasury: 582, insurance: 391, sp: 985});
});

it('SP filtering during deposit works when doing a huge deposit', async () => {
Expand Down
30 changes: 17 additions & 13 deletions test/0.4.24/depool_w_steth.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,15 +214,16 @@ contract('DePool with StEth', ([appManager, voting, user1, user2, user3, nobody]
assertBn(await token.balanceOf(user2), new BN('34990001971093930278'));
assertBn(await token.balanceOf(treasuryAddr), new BN('00002999143026093765'));
assertBn(await token.balanceOf(insuranceAddr), new BN('00001999600063664000'));
//FixMe: will be distributed among sps'es
assertBn(await token.balanceOf(sps.address), new BN('00004999285816311955'));

assertBn(await token.balanceOf(ADDRESS_1), new BN('00004999285816311954'));
});
it('stETH shares: total=34.01 user2=34 treasury.003, insurance=.002, sps=.004', async () => {
assertBn(await token.getTotalShares(), new BN('34009715146146239066'));
assertBn(await token.getSharesByHolder(user2), tokens(34)); //stays the same
assertBn(await token.getSharesByHolder(treasuryAddr), new BN('00002914285714285714'));
assertBn(await token.getSharesByHolder(insuranceAddr), new BN('00001943023673469387'));
assertBn(await token.getSharesByHolder(sps.address), new BN('00004857836758483965'));

assertBn(await token.getSharesByHolder(ADDRESS_1), new BN('00004857836758483964'));
});
});
});
Expand All @@ -244,17 +245,18 @@ contract('DePool with StEth', ([appManager, voting, user1, user2, user3, nobody]
assertBn(await token.balanceOf(user2), new BN('67661169524583879360'));
assertBn(await token.balanceOf(treasuryAddr), new BN('101491754286875819'));
assertBn(await token.balanceOf(insuranceAddr), new BN('67762661278870755'));
//FixMe: will be distributed among sps'es
assertBn(await token.balanceOf(sps.address), new BN('169576059850374064'));

assertBn(await token.balanceOf(ADDRESS_1), new BN('169576059850374062'));
});
it('stETH shares: total=34.17 user2=34 treasury=.05, insurance=.03, sps=.09', async () => {
assertBn(await token.getTotalShares(), new BN('34170263627500000000'));
assertBn(await token.getSharesByHolder(user2), tokens(34)); //stays the same
assertBn(await token.getSharesByHolder(treasuryAddr), new BN('51000000000000000'));
assertBn(await token.getSharesByHolder(insuranceAddr), new BN('34051000000000000'));
assertBn(await token.getSharesByHolder(sps.address), new BN('85212627500000000'));

assertBn(await token.getSharesByHolder(ADDRESS_1), new BN('85212627499999999'));
});

context('user3 submits 34 ETH (submitted but not propagated to ETH2 yet)', async () => {
beforeEach(async function () {
await web3.eth.sendTransaction({to: app.address, from: user3, value: ETH(34)});
Expand All @@ -273,16 +275,17 @@ contract('DePool with StEth', ([appManager, voting, user1, user2, user3, nobody]
assertBn(await token.balanceOf(user3), new BN('23333333333333333333'));
assertBn(await token.balanceOf(treasuryAddr), new BN('00069651203922365758'));
assertBn(await token.balanceOf(insuranceAddr), new BN('00046503787152166204'));
//FixMe: will be distributed among sps'es
assertBn(await token.balanceOf(sps.address), new BN('00116375727348295926'));

assertBn(await token.balanceOf(ADDRESS_1), new BN('00116375727348295925'));
});
it('stETH shares: total=51.255 user2=34 user3=17.085 treasury=.051, insurance=.034, sps=.085', async () => {
assertBn(await token.getTotalShares(), new BN('51255395441250000000'));
assertBn(await token.getSharesByHolder(user2), tokens(34)); //stays the same
assertBn(await token.getSharesByHolder(user3), new BN('17085131813750000000'));
assertBn(await token.getSharesByHolder(treasuryAddr), new BN('51000000000000000'));
assertBn(await token.getSharesByHolder(insuranceAddr), new BN('34051000000000000'));
assertBn(await token.getSharesByHolder(sps.address), new BN('85212627500000000'));

assertBn(await token.getSharesByHolder(ADDRESS_1), new BN('85212627499999999'));
});
context('oracle reports 98 ETH (66 existing + 32 new). No rewards at this point', async () => {
beforeEach(async function () {
Expand All @@ -302,16 +305,17 @@ contract('DePool with StEth', ([appManager, voting, user1, user2, user3, nobody]
assertBn(await token.balanceOf(user3), new BN('34000000000000000000'));
assertBn(await token.balanceOf(treasuryAddr), new BN('00101491754286875819'));
assertBn(await token.balanceOf(insuranceAddr), new BN('00067762661278870755'));
//FixMe: will be distributed among sps'es
assertBn(await token.balanceOf(sps.address), new BN('00169576059850374064'));

assertBn(await token.balanceOf(ADDRESS_1), new BN('00169576059850374062'));
});
it('stETH shares: total=51.255 user2=34 user3=17.085 treasury=.051, insurance=.034, sps=.085 (same as before)', async () => {
assertBn(await token.getTotalShares(), new BN('51255395441250000000'));
assertBn(await token.getSharesByHolder(user2), tokens(34)); //stays the same
assertBn(await token.getSharesByHolder(user3), new BN('17085131813750000000'));
assertBn(await token.getSharesByHolder(treasuryAddr), new BN('51000000000000000'));
assertBn(await token.getSharesByHolder(insuranceAddr), new BN('3405100000000 5A21 0000'));
assertBn(await token.getSharesByHolder(sps.address), new BN('85212627500000000'));

assertBn(await token.getSharesByHolder(ADDRESS_1), new BN('85212627499999999'));
});
});
});
Expand Down
Loading
0