Skip to content

Commit

Permalink
Add assertions to test reward calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
DrZoltanFazekas committed Dec 11, 2024
1 parent 83500eb commit 50ca3e9
Showing 1 changed file with 80 additions and 68 deletions.
148 changes: 80 additions & 68 deletions test/NonLiquidDelegation.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ import {Console} from "src/Console.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {Vm} from "forge-std/Test.sol";
import "forge-std/console.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";

contract NonLiquidDelegationTest is BaseDelegationTest {
using SafeCast for int256;

NonLiquidDelegationV2 delegation;

constructor() BaseDelegationTest() {
Expand Down Expand Up @@ -40,42 +43,48 @@ contract NonLiquidDelegationTest is BaseDelegationTest {
revert("staker not found");
}

function snapshot(string memory s, uint256 i, uint256 x) internal view {
function snapshot(string memory s, uint256 i, uint256 x) internal view returns(uint256 calculatedRewards) {
console.log("-----------------------------------------------");
console.log(s, i, x);
uint256[] memory shares = new uint256[](stakers.length);
NonLiquidDelegationV2.Staking[] memory stakings = delegation.getStakingHistory();
for (i = 0; i < stakings.length; i++)
//i = stakings.length - 1;
for (uint256 k = 0; k < stakings.length; k++)
//k = stakings.length - 1;
{
uint256 stakerIndex = findStaker(stakings[i].staker);
shares[stakerIndex] = stakings[i].amount;
s = string.concat("index: ", Strings.toString(i));
uint256 stakerIndex = findStaker(stakings[k].staker);
shares[stakerIndex] = stakings[k].amount;
s = string.concat("index: ", Strings.toString(k));
s = string.concat(s, "\tstaker ");
assertEq(stakings[i].staker, stakers[stakerIndex], "found staker mismatch");
assertEq(stakings[k].staker, stakers[stakerIndex], "found staker mismatch");
s = string.concat(s, Strings.toString(stakerIndex + 1));
s = string.concat(s, ": ");
s = string.concat(s, Strings.toHexString(stakings[i].staker));
s = string.concat(s, Strings.toHexString(stakings[k].staker));
s = string.concat(s, " amount: ");
s = string.concat(s, Strings.toString(stakings[i].amount / 1 ether));
s = string.concat(s, Strings.toString(stakings[k].amount / 1 ether));
s = string.concat(s, "\ttotal: ");
s = string.concat(s, Strings.toString(stakings[i].total / 1 ether));
if (stakings[i].total < 100_000_000 ether)
s = string.concat(s, Strings.toString(stakings[k].total / 1 ether));
if (stakings[k].total < 100_000_000 ether)
s = string.concat(s, "\t");
s = string.concat(s, "\trewards: ");
s = string.concat(s, Strings.toString(stakings[i].rewards / 1 ether));
s = string.concat(s, "\tshares: ");
s = string.concat(s, Strings.toString(stakings[k].rewards / 1 ether));
if (stakings[k].rewards < 10_000 ether)
s = string.concat(s, "\t");
s = string.concat(s, "\t\tshares:\t");
for (uint256 j = 0; j < shares.length; j++)
if (stakings[i].total != 0) {
string memory s0 = string.concat(Console.toString(10**6 * shares[j] / stakings[i].total, 4), "%");
if (bytes(s0).length <= 7)
if (stakings[k].total != 0) {
string memory s0 = string.concat(Console.toString(10**6 * shares[j] / stakings[k].total, 4), "%");
if (bytes(s0).length < 8)
s0 = string.concat(s0, "\t\t");
else
s0 = string.concat(s0, "\t");
s = string.concat(s, s0);
} else
s = string.concat(s, "0.0%\t\t");
console.log(s);
if (k < stakings.length - 1)
calculatedRewards += stakings[k+1].rewards * shares[i-1] / stakings[k].total;
else
calculatedRewards += (int256(delegation.getRewards()) - delegation.getTotalRewards()).toUint256() * shares[i-1] / stakings[k].total;
}
(
uint64[] memory stakingIndices,
Expand Down Expand Up @@ -147,20 +156,32 @@ contract NonLiquidDelegationTest is BaseDelegationTest {
//no rewards if we withdraw in the same block as the last staking
//vm.deal(address(delegation), address(delegation).balance + rewardsAccruedAfterEach);

uint256[] memory calculatedRewards = new uint256[](stakers.length);
uint256[] memory availableRewards = new uint256[](stakers.length);
uint256[] memory withdrawnRewards = new uint256[](stakers.length);
for (uint256 i = 1; i <= 2; i++) {
vm.startPrank(stakers[i-1]);
if (steps == 123_456_789)
snapshot("staker %s withdrawing all, remaining rewards:", i, 0);
else
calculatedRewards[i-1] =
steps == 123_456_789 ?
snapshot("staker %s withdrawing all, remaining rewards:", i, 0) :
snapshot("staker %s withdrawing 1+%s times", i, steps);
Console.log("rewards accrued until last staking: %s.%s%s", delegation.getTotalRewards());
Console.log("delegation contract balance: %s.%s%s", address(delegation).balance);
//Console.log("staker balance: %s.%s%s", stakers[i-1].balance);
Console.log("staker rewards: %s.%s%s", delegation.rewards());
if (steps == 123_456_789)
Console.log("staker withdrew: %s.%s%s", delegation.withdrawAllRewards());
else
Console.log("staker withdrew: %s.%s%s", delegation.withdrawRewards(delegation.rewards(steps), steps));
Console.log("calculated rewards: %s.%s%s", calculatedRewards[i-1] * (delegation.DENOMINATOR() - delegation.getCommissionNumerator()) / delegation.DENOMINATOR());
availableRewards[i-1] = delegation.rewards();
Console.log("staker rewards: %s.%s%s", availableRewards[i-1]);
withdrawnRewards[i-1] =
steps == 123_456_789 ?
delegation.withdrawAllRewards() :
delegation.withdrawRewards(delegation.rewards(steps), steps);
Console.log("staker withdrew: %s.%s%s", withdrawnRewards[i-1]);
assertApproxEqAbs(
calculatedRewards[i-1] * (delegation.DENOMINATOR() - delegation.getCommissionNumerator()) / delegation.DENOMINATOR(),
availableRewards[i-1],
9,
"rewards differ from calculated value"
);
Console.log("rewards accrued until last staking: %s.%s%s", delegation.getTotalRewards());
Console.log("delegation contract balance: %s.%s%s", address(delegation).balance);
//Console.log("staker balance: %s.%s%s", stakers[i-1].balance);
Expand All @@ -186,51 +207,42 @@ contract NonLiquidDelegationTest is BaseDelegationTest {
//further rewards accrued since the last staking
vm.deal(address(delegation), address(delegation).balance + rewardsAccruedAfterEach);

for (uint256 i = 1; i <= stakers.length; i++) {
vm.startPrank(stakers[i-1]);
if (steps == 123_456_789)
snapshot("staker %s withdrawing all, remaining rewards:", i, 0);
else
snapshot("staker %s withdrawing 1+%s times", i, steps);
Console.log("rewards accrued until last staking: %s.%s%s", delegation.getTotalRewards());
Console.log("delegation contract balance: %s.%s%s", address(delegation).balance);
//Console.log("staker balance: %s.%s%s", stakers[i-1].balance);
Console.log("staker rewards: %s.%s%s", delegation.rewards());
if (steps == 123_456_789)
Console.log("staker withdrew: %s.%s%s", delegation.withdrawAllRewards());
else
//TODO: add a test that withdraws a fixed amount < delegation.rewards(step)
Console.log("staker withdrew: %s.%s%s", delegation.withdrawRewards(delegation.rewards(steps), steps));
Console.log("rewards accrued until last staking: %s.%s%s", delegation.getTotalRewards());
Console.log("delegation contract balance: %s.%s%s", address(delegation).balance);
//Console.log("staker balance: %s.%s%s", stakers[i-1].balance);
vm.stopPrank();
}

// if we try to withdraw again immediately (in the same block),
// the amount withdrawn must equal zero
//*
for (uint256 i = 1; i <= stakers.length; i++) {
vm.startPrank(stakers[i-1]);
if (steps == 123_456_789)
snapshot("staker %s withdrawing all, remaining rewards:", i, 0);
else
snapshot("staker %s withdrawing 1+%s times", i, steps);
Console.log("rewards accrued until last staking: %s.%s%s", delegation.getTotalRewards());
Console.log("delegation contract balance: %s.%s%s", address(delegation).balance);
//Console.log("staker balance: %s.%s%s", stakers[i-1].balance);
Console.log("staker rewards: %s.%s%s", delegation.rewards());
if (steps == 123_456_789)
Console.log("staker withdrew: %s.%s%s", delegation.withdrawAllRewards());
else
// withdraw rewards 5 times in the same block
// i.e. without additional reward accrual
for (uint256 r = 0; r < 5; r++)
for (uint256 i = 1; i <= stakers.length; i++) {
vm.startPrank(stakers[i-1]);
calculatedRewards[i-1] =
steps == 123_456_789 ?
snapshot("staker %s withdrawing all, remaining rewards:", i, 0) :
snapshot("staker %s withdrawing 1+%s times", i, steps);
int256 temp = int256(calculatedRewards[i-1]) - int256(withdrawnRewards[i-1] * delegation.DENOMINATOR() / (delegation.DENOMINATOR() - delegation.getCommissionNumerator()));
calculatedRewards[i-1] = (temp > 0 ? temp : -temp).toUint256();
Console.log("rewards accrued until last staking: %s.%s%s", delegation.getTotalRewards());
Console.log("delegation contract balance: %s.%s%s", address(delegation).balance);
//Console.log("staker balance: %s.%s%s", stakers[i-1].balance);
Console.log("calculated rewards: %s.%s%s", calculatedRewards[i-1] * (delegation.DENOMINATOR() - delegation.getCommissionNumerator()) / delegation.DENOMINATOR());
availableRewards[i-1] = delegation.rewards();
Console.log("staker rewards: %s.%s%s", availableRewards[i-1]);
uint256 withdrawnReward =
steps == 123_456_789 ?
delegation.withdrawAllRewards() :
delegation.withdrawRewards(delegation.rewards(steps), steps);
Console.log("staker withdrew now: %s.%s%s", withdrawnReward);
withdrawnRewards[i-1] += withdrawnReward;
Console.log("staker withdrew altogether: %s.%s%s", withdrawnRewards[i-1]);
assertApproxEqAbs(
calculatedRewards[i-1] * (delegation.DENOMINATOR() - delegation.getCommissionNumerator()) / delegation.DENOMINATOR(),
availableRewards[i-1],
9,
"rewards differ from calculated value"
);
//TODO: add a test that withdraws a fixed amount < delegation.rewards(step)
Console.log("staker withdrew: %s.%s%s", delegation.withdrawRewards(delegation.rewards(steps), steps));
Console.log("rewards accrued until last staking: %s.%s%s", delegation.getTotalRewards());
Console.log("delegation contract balance: %s.%s%s", address(delegation).balance);
//Console.log("staker balance: %s.%s%s", stakers[i-1].balance);
vm.stopPrank();
}
//*/
Console.log("rewards accrued until last staking: %s.%s%s", delegation.getTotalRewards());
Console.log("delegation contract balance: %s.%s%s", address(delegation).balance);
//Console.log("staker balance: %s.%s%s", stakers[i-1].balance);
vm.stopPrank();
}
}

function test_withdrawAllRewards_OwnDeposit() public {
Expand Down

0 comments on commit 50ca3e9

Please sign in to comment.