From a432d3fd81efdca13f00e498713a3eb2b999d0cb Mon Sep 17 00:00:00 2001 From: r4bbit <445106+0x-r4bbit@users.noreply.github.com> Date: Thu, 12 Dec 2024 13:32:14 +0100 Subject: [PATCH] cleanup: remove unused `RewardStreamer` contract This was some version of the staking contract for demonstration purposes and is not actually used as we're working on `RewardStreamerMP` version, which is aware of multiplier points. Closes #84 --- .gas-report | 23 +---- .gas-snapshot | 1 - src/RewardsStreamer.sol | 126 ----------------------- test/RewardsStreamer.t.sol | 206 ------------------------------------- 4 files changed, 4 insertions(+), 352 deletions(-) delete mode 100644 src/RewardsStreamer.sol delete mode 100644 test/RewardsStreamer.t.sol diff --git a/.gas-report b/.gas-report index bd20e13..b2c4941 100644 --- a/.gas-report +++ b/.gas-report @@ -22,20 +22,6 @@ | run | 2383391 | 2383391 | 2383391 | 2383391 | 3 | -| src/RewardsStreamer.sol:RewardsStreamer contract | | | | | | -|--------------------------------------------------|-----------------|--------|--------|--------|---------| -| Deployment Cost | Deployment Size | | | | | -| 677674 | 3080 | | | | | -| Function Name | min | avg | median | max | # calls | -| accountedRewards | 350 | 600 | 350 | 2350 | 8 | -| getUserInfo | 789 | 789 | 789 | 789 | 12 | -| rewardIndex | 349 | 599 | 349 | 2349 | 8 | -| stake | 85202 | 100705 | 105102 | 111812 | 3 | -| totalStaked | 350 | 350 | 350 | 350 | 8 | -| unstake | 110056 | 110062 | 110062 | 110068 | 2 | -| updateRewardIndex | 23372 | 45573 | 39574 | 73774 | 3 | - - | src/RewardsStreamerMP.sol:RewardsStreamerMP contract | | | | | | |------------------------------------------------------|-----------------|--------|--------|--------|---------| | Deployment Cost | Deployment Size | | | | | @@ -201,12 +187,11 @@ | test/mocks/MockToken.sol:MockToken contract | | | | | | |---------------------------------------------|-----------------|-------|--------|-------|---------| | Deployment Cost | Deployment Size | | | | | -| 625370 | 3260 | | | | | +| 625454 | 3260 | | | | | | Function Name | min | avg | median | max | # calls | -| approve | 46330 | 46339 | 46342 | 46342 | 262 | -| balanceOf | 558 | 989 | 558 | 2558 | 139 | -| mint | 51279 | 56438 | 51279 | 68379 | 275 | -| transfer | 34384 | 42934 | 42934 | 51484 | 2 | +| approve | 46330 | 46339 | 46342 | 46342 | 257 | +| balanceOf | 558 | 926 | 558 | 2558 | 103 | +| mint | 51279 | 56407 | 51279 | 68379 | 270 | | test/mocks/StackOverflowStakeManager.sol:StackOverflowStakeManager contract | | | | | | diff --git a/.gas-snapshot b/.gas-snapshot index 1f09771..dcc33ee 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -33,7 +33,6 @@ RewardsStreamerMP_RewardsTest:testSetRewards_RevertsBadAmount() (gas: 39404) RewardsStreamerMP_RewardsTest:testSetRewards_RevertsBadDuration() (gas: 39340) RewardsStreamerMP_RewardsTest:testSetRewards_RevertsNotAuthorized() (gas: 39375) RewardsStreamerMP_RewardsTest:testTotalRewardsSupply() (gas: 610662) -RewardsStreamerTest:testStake() (gas: 869181) StakeTest:test_StakeMultipleAccounts() (gas: 494442) StakeTest:test_StakeMultipleAccountsAndRewards() (gas: 500380) StakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 830612) diff --git a/src/RewardsStreamer.sol b/src/RewardsStreamer.sol deleted file mode 100644 index 19e3585..0000000 --- a/src/RewardsStreamer.sol +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; - -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; - -contract RewardsStreamer is ReentrancyGuard { - error StakingManager__AmountCannotBeZero(); - error StakingManager__TransferFailed(); - error StakingManager__InsufficientBalance(); - - IERC20 public immutable STAKING_TOKEN; - IERC20 public immutable REWARD_TOKEN; - - uint256 public constant SCALE_FACTOR = 1e18; - - uint256 public totalStaked; - uint256 public rewardIndex; - uint256 public accountedRewards; - - struct UserInfo { - uint256 stakedBalance; - uint256 userRewardIndex; - } - - mapping(address account => UserInfo data) public users; - - constructor(address _stakingToken, address _rewardToken) { - STAKING_TOKEN = IERC20(_stakingToken); - REWARD_TOKEN = IERC20(_rewardToken); - } - - function stake(uint256 amount) external nonReentrant { - if (amount == 0) { - revert StakingManager__AmountCannotBeZero(); - } - - updateRewardIndex(); - - UserInfo storage user = users[msg.sender]; - uint256 userRewards = calculateUserRewards(msg.sender); - if (userRewards > 0) { - distributeRewards(msg.sender, userRewards); - } - - bool success = STAKING_TOKEN.transferFrom(msg.sender, address(this), amount); - if (!success) { - revert StakingManager__TransferFailed(); - } - - user.stakedBalance += amount; - totalStaked += amount; - user.userRewardIndex = rewardIndex; - } - - function unstake(uint256 amount) external nonReentrant { - UserInfo storage user = users[msg.sender]; - if (amount > user.stakedBalance) { - revert StakingManager__InsufficientBalance(); - } - - updateRewardIndex(); - - uint256 userRewards = calculateUserRewards(msg.sender); - if (userRewards > 0) { - distributeRewards(msg.sender, userRewards); - } - - user.stakedBalance -= amount; - totalStaked -= amount; - - bool success = STAKING_TOKEN.transfer(msg.sender, amount); - if (!success) { - revert StakingManager__TransferFailed(); - } - - user.userRewardIndex = rewardIndex; - } - - function updateRewardIndex() public { - if (totalStaked == 0) { - return; - } - - uint256 rewardBalance = REWARD_TOKEN.balanceOf(address(this)); - uint256 newRewards = rewardBalance > accountedRewards ? rewardBalance - accountedRewards : 0; - - if (newRewards > 0) { - rewardIndex += (newRewards * SCALE_FACTOR) / totalStaked; - accountedRewards += newRewards; - } - } - - function getStakedBalance(address userAddress) public view returns (uint256) { - return users[userAddress].stakedBalance; - } - - function getPendingRewards(address userAddress) public view returns (uint256) { - return calculateUserRewards(userAddress); - } - - function calculateUserRewards(address userAddress) public view returns (uint256) { - UserInfo storage user = users[userAddress]; - return (user.stakedBalance * (rewardIndex - user.userRewardIndex)) / SCALE_FACTOR; - } - - // send the rewards and updates accountedRewards - function distributeRewards(address to, uint256 amount) internal { - uint256 rewardBalance = REWARD_TOKEN.balanceOf(address(this)); - // If amount is higher than the contract's balance (for rounding error), transfer the balance. - if (amount > rewardBalance) { - amount = rewardBalance; - } - - accountedRewards -= amount; - - bool success = REWARD_TOKEN.transfer(to, amount); - if (!success) { - revert StakingManager__TransferFailed(); - } - } - - function getUserInfo(address userAddress) public view returns (UserInfo memory) { - return users[userAddress]; - } -} diff --git a/test/RewardsStreamer.t.sol b/test/RewardsStreamer.t.sol deleted file mode 100644 index 32c15a1..0000000 --- a/test/RewardsStreamer.t.sol +++ /dev/null @@ -1,206 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.26; - -import { Test } from "forge-std/Test.sol"; -import { RewardsStreamer } from "../src/RewardsStreamer.sol"; -import { MockToken } from "./mocks/MockToken.sol"; - -contract RewardsStreamerTest is Test { - MockToken rewardToken; - MockToken stakingToken; - RewardsStreamer public streamer; - - address admin = makeAddr("admin"); - address alice = makeAddr("alice"); - address bob = makeAddr("bob"); - address charlie = makeAddr("charlie"); - address dave = makeAddr("dave"); - - function setUp() public { - rewardToken = new MockToken("Reward Token", "RT"); - stakingToken = new MockToken("Staking Token", "ST"); - streamer = new RewardsStreamer(address(stakingToken), address(rewardToken)); - - address[4] memory users = [alice, bob, charlie, dave]; - for (uint256 i = 0; i < users.length; i++) { - stakingToken.mint(users[i], 10_000e18); - vm.prank(users[i]); - stakingToken.approve(address(streamer), 10_000e18); - } - - rewardToken.mint(admin, 10_000e18); - vm.prank(admin); - rewardToken.approve(address(streamer), 10_000e18); - } - - struct CheckStreamerParams { - uint256 totalStaked; - uint256 stakingBalance; - uint256 rewardBalance; - uint256 rewardIndex; - uint256 accountedRewards; - } - - function checkStreamer(CheckStreamerParams memory p) public view { - assertEq(streamer.totalStaked(), p.totalStaked); - assertEq(stakingToken.balanceOf(address(streamer)), p.stakingBalance); - assertEq(rewardToken.balanceOf(address(streamer)), p.rewardBalance); - assertEq(streamer.rewardIndex(), p.rewardIndex); - assertEq(streamer.accountedRewards(), p.accountedRewards); - } - - struct CheckUserParams { - address user; - uint256 rewardBalance; - uint256 stakedBalance; - uint256 rewardIndex; - } - - function checkUser(CheckUserParams memory p) public view { - assertEq(rewardToken.balanceOf(p.user), p.rewardBalance); - - RewardsStreamer.UserInfo memory userInfo = streamer.getUserInfo(p.user); - - assertEq(userInfo.stakedBalance, p.stakedBalance); - assertEq(userInfo.userRewardIndex, p.rewardIndex); - } - - function testStake() public { - streamer.updateRewardIndex(); - - // T0 - checkStreamer( - CheckStreamerParams({ - totalStaked: 0, - stakingBalance: 0, - rewardBalance: 0, - rewardIndex: 0, - accountedRewards: 0 - }) - ); - - // T1 - vm.prank(alice); - streamer.stake(10e18); - - checkStreamer( - CheckStreamerParams({ - totalStaked: 10e18, - stakingBalance: 10e18, - rewardBalance: 0, - rewardIndex: 0, - accountedRewards: 0 - }) - ); - - // T2 - vm.prank(bob); - streamer.stake(30e18); - - checkStreamer( - CheckStreamerParams({ - totalStaked: 40e18, - stakingBalance: 40e18, - rewardBalance: 0, - rewardIndex: 0, - accountedRewards: 0 - }) - ); - - // T3 - vm.prank(admin); - rewardToken.transfer(address(streamer), 1000e18); - streamer.updateRewardIndex(); - - checkStreamer( - CheckStreamerParams({ - totalStaked: 40e18, - stakingBalance: 40e18, - rewardBalance: 1000e18, - rewardIndex: 25e18, - accountedRewards: 1000e18 - }) - ); - - checkUser(CheckUserParams({ user: alice, rewardBalance: 0, stakedBalance: 10e18, rewardIndex: 0 })); - checkUser(CheckUserParams({ user: bob, rewardBalance: 0, stakedBalance: 30e18, rewardIndex: 0 })); - - // T4 - vm.prank(alice); - streamer.unstake(10e18); - - checkStreamer( - CheckStreamerParams({ - totalStaked: 30e18, - stakingBalance: 30e18, - rewardBalance: 750e18, - rewardIndex: 25e18, - accountedRewards: 750e18 - }) - ); - - checkUser(CheckUserParams({ user: alice, rewardBalance: 250e18, stakedBalance: 0e18, rewardIndex: 25e18 })); - checkUser(CheckUserParams({ user: bob, rewardBalance: 0, stakedBalance: 30e18, rewardIndex: 0 })); - - // T5 - vm.prank(charlie); - streamer.stake(30e18); - - checkStreamer( - CheckStreamerParams({ - totalStaked: 60e18, - stakingBalance: 60e18, - rewardBalance: 750e18, - rewardIndex: 25e18, - accountedRewards: 750e18 - }) - ); - - checkUser(CheckUserParams({ user: alice, rewardBalance: 250e18, stakedBalance: 0e18, rewardIndex: 25e18 })); - checkUser(CheckUserParams({ user: bob, rewardBalance: 0, stakedBalance: 30e18, rewardIndex: 0 })); - checkUser(CheckUserParams({ user: charlie, rewardBalance: 0, stakedBalance: 30e18, rewardIndex: 25e18 })); - - // T6 - vm.prank(admin); - rewardToken.transfer(address(streamer), 1000e18); - streamer.updateRewardIndex(); - - checkStreamer( - CheckStreamerParams({ - totalStaked: 60e18, - stakingBalance: 60e18, - rewardBalance: 1750e18, - rewardIndex: 41_666_666_666_666_666_666, - accountedRewards: 1750e18 - }) - ); - - checkUser(CheckUserParams({ user: alice, rewardBalance: 250e18, stakedBalance: 0, rewardIndex: 25e18 })); - checkUser(CheckUserParams({ user: bob, rewardBalance: 0, stakedBalance: 30e18, rewardIndex: 0 })); - checkUser(CheckUserParams({ user: charlie, rewardBalance: 0, stakedBalance: 30e18, rewardIndex: 25e18 })); - - //T7 - vm.prank(bob); - streamer.unstake(30e18); - - checkStreamer( - CheckStreamerParams({ - totalStaked: 30e18, - stakingBalance: 30e18, - rewardBalance: 500e18 + 20, // 500e18 (with rounding error of 20 wei) - rewardIndex: 41_666_666_666_666_666_666, - accountedRewards: 500e18 + 20 - }) - ); - - checkUser(CheckUserParams({ user: alice, rewardBalance: 250e18, stakedBalance: 0, rewardIndex: 25e18 })); - checkUser( - CheckUserParams({ - user: bob, - rewardBalance: 1_249_999_999_999_999_999_980, // 750e18 + 500e18 (with rounding error) - stakedBalance: 0, - rewardIndex: 41_666_666_666_666_666_666 - }) - ); - } -}