diff --git a/contracts/staking/token/DoubleSidePool.sol b/contracts/staking/token/DoubleSidePool.sol index cb6eff8..302c249 100644 --- a/contracts/staking/token/DoubleSidePool.sol +++ b/contracts/staking/token/DoubleSidePool.sol @@ -8,8 +8,6 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../../funds/RewardsBank.sol"; import "../../LockKeeper.sol"; -import "hardhat/console.sol"; - //The side defined by the address of the token. Zero address means native coin contract DoubleSidePool is Initializable, AccessControl, IOnBlockListener { @@ -199,133 +197,64 @@ contract DoubleSidePool is Initializable, AccessControl, IOnBlockListener { // PUBLIC METHODS - function stake(bool dependant, uint amount) public { - if (dependant) { - _stakeDependantSide(msg.sender, amount); - } else { - _stakeMainSide(msg.sender, amount); - } - } - - function unstake(bool dependant, uint amount) public { - if (dependant) { - _unstakeDependantSide(msg.sender, amount); - } else { - _unstakeMainSide(msg.sender, amount); - } - } - - function unstakeFast(bool dependant, uint amount) public { - if (dependant) { - _unstakeFastDependantSide(msg.sender, amount); - } else { - _unstakeFastMainSide(msg.sender, amount); - } - } - - function claim(bool dependant) public { - if (dependant) { - _calcClaimableRewards(true, msg.sender); - _claimRewards(true, msg.sender); + function stakeMainSide(uint amount) public payable { + require(active, "Pool is not active"); + require(amount >= mainSideConfig.minStakeValue, "Pool: stake value is too low"); + if (msg.value != 0) { + require(mainSideConfig.token == address(0), "Pool: does not accept native coin"); + require(msg.value == amount, "Pool: wrong amount of native coin"); } else { - _calcClaimableRewards(false, msg.sender); - _claimRewards(false, msg.sender); + SafeERC20.safeTransferFrom(IERC20(mainSideConfig.token), msg.sender, address(this), amount); } - } - function onBlock() external { - _addInterestMainSide(); - _addInterestDependantSide(); - } - - // VIEW METHODS - - function getMainSideConfig() public view returns (MainSideConfig memory) { - return mainSideConfig; - } + uint rewardsAmount = _calcRewardsMainSide(amount); - function getMainSideInfo() public view returns (SideInfo memory) { - return mainSideInfo; - } - - function getMainSideStaker(address user) public view returns (SideStaker memory) { - return mainSideStakers[user]; - } - - function getDependantSideConfig() public view returns (DependantSideConfig memory) { - return dependantSideConfig; - } - - function getDependantSideInfo() public view returns (SideInfo memory) { - return dependantSideInfo; - } - - function getDependantSideStaker(address user) public view returns (SideStaker memory) { - return dependantSideStakers[user]; - } - - function getUserMainSideRewards(address user) public view returns (uint) { - uint rewardsAmount = _calcRewards(false, mainSideStakers[user].stake); - if (rewardsAmount + mainSideStakers[user].claimableRewards <= mainSideStakers[user].rewardsDebt) - return 0; - - return rewardsAmount + mainSideStakers[user].claimableRewards - mainSideStakers[user].rewardsDebt; - } - - function getUserDependantSideRewards(address user) public view returns (uint) { - uint rewardsAmount = _calcRewards(true, dependantSideStakers[user].stake); - if (rewardsAmount + dependantSideStakers[user].claimableRewards <= dependantSideStakers[user].rewardsDebt) - return 0; - - return rewardsAmount + dependantSideStakers[user].claimableRewards - dependantSideStakers[user].rewardsDebt; - } - - // INTERNAL METHODS - - // MAIN SIDE METHODS + mainSideStakers[msg.sender].stake += amount; + mainSideInfo.totalStake += amount; - function _addInterestMainSide() internal { - uint timePassed = block.timestamp - mainSideInfo.lastInterestUpdate; - uint newRewards = mainSideInfo.totalStake * mainSideConfig.interest * timePassed / BILLION / mainSideConfig.interestRate; + mainSideInfo.totalRewards += rewardsAmount; - mainSideInfo.totalRewards += newRewards; - mainSideInfo.lastInterestUpdate = block.timestamp; - emit Interest(false, newRewards); + _updateRewardsDebtMainSide(msg.sender, _calcRewardsMainSide(mainSideStakers[msg.sender].stake)); + emit StakeChanged(false, msg.sender, amount); } - - function _stakeMainSide(address user, uint amount) internal { + function stakeDependantSide(uint amount) public payable { require(active, "Pool is not active"); - require(amount >= mainSideConfig.minStakeValue, "Pool: stake value is too low"); + require(amount >= dependantSideConfig.minStakeValue, "Pool: stake value is too low"); if (msg.value != 0) { require(mainSideConfig.token == address(0), "Pool: does not accept native coin"); require(msg.value == amount, "Pool: wrong amount of native coin"); } else { - SafeERC20.safeTransferFrom(IERC20(mainSideConfig.token), msg.sender, address(this), amount); + SafeERC20.safeTransferFrom(IERC20(dependantSideConfig.token), msg.sender, address(this), amount); } - uint rewardsAmount = _calcRewards(false, amount); + uint rewardsAmount = _calcRewardsDependantSide(amount); - mainSideStakers[msg.sender].stake += amount; - mainSideInfo.totalStake += amount; + dependantSideStakers[msg.sender].stake += amount; + dependantSideInfo.totalStake += amount; + if (dependantSideStakers[msg.sender].stakedAt == 0) + dependantSideStakers[msg.sender].stakedAt = block.timestamp; - mainSideInfo.totalRewards += rewardsAmount; + require(dependantSideStakers[msg.sender].stake <= _maxUserStakeValue(msg.sender), "Pool: user max stake value exceeded"); + require(dependantSideInfo.totalStake <= dependantSideConfig.maxTotalStakeValue, "Pool: max stake value exceeded"); + require(dependantSideStakers[msg.sender].stake <= dependantSideConfig.maxStakePerUserValue, "Pool: max stake per user exceeded"); - _updateRewardsDebt(false, user, _calcRewards(false, mainSideStakers[user].stake)); - emit StakeChanged(false, msg.sender, amount); - } + dependantSideInfo.totalRewards += rewardsAmount; + _updateRewardsDebtDependantSide(msg.sender, _calcRewardsDependantSide(dependantSideStakers[msg.sender].stake)); + emit StakeChanged(true, msg.sender, amount); + } - function _unstakeMainSide(address user, uint amount) internal { + function unstakeMainSide(uint amount) public { require(mainSideStakers[msg.sender].stake >= amount, "Not enough stake"); - uint rewardsAmount = _calcRewards(false, amount); + uint rewardsAmount = _calcRewardsMainSide(amount); mainSideStakers[msg.sender].stake -= amount; mainSideInfo.totalStake -= amount; mainSideInfo.totalRewards -= rewardsAmount; - _updateRewardsDebt(false, user, _calcRewards(false, mainSideStakers[user].stake)); + _updateRewardsDebtMainSide(msg.sender, _calcRewardsMainSide(mainSideStakers[msg.sender].stake)); // cancel previous lock (if exists). canceledAmount will be added to new lock uint canceledAmount; @@ -347,87 +276,17 @@ contract DoubleSidePool is Initializable, AccessControl, IOnBlockListener { ); } - - _claimRewards(false, msg.sender); + _claimRewardsMainSide(msg.sender); emit UnstakeLocked(false, msg.sender, amount + canceledAmount, block.timestamp + mainSideConfig.lockPeriod, block.timestamp); emit StakeChanged(false, msg.sender, mainSideStakers[msg.sender].stake); } - - function _unstakeFastMainSide(address user, uint amount) internal { - require(mainSideStakers[msg.sender].stake >= amount, "Not enough stake"); - - uint rewardsAmount = _calcRewards(false, amount); - - mainSideStakers[msg.sender].stake -= amount; - mainSideInfo.totalStake -= amount; - - mainSideInfo.totalRewards -= rewardsAmount; - _updateRewardsDebt(false, user, _calcRewards(false, mainSideStakers[user].stake)); - - uint penalty = amount * mainSideConfig.fastUnstakePenalty / BILLION; - if (mainSideConfig.token == address(0)) { - payable(msg.sender).transfer(amount - penalty); - } else { - SafeERC20.safeTransfer(IERC20(mainSideConfig.token), msg.sender, amount - penalty); - } - - _claimRewards(false, msg.sender); - - emit UnstakeFast(false, msg.sender, amount, penalty); - emit StakeChanged(false, msg.sender, amount); - } - - // DEPENDANT SIDE METHODS - - function _addInterestDependantSide() internal { - if (!hasSecondSide) return; - if (dependantSideInfo.lastInterestUpdate + dependantSideConfig.interestRate > block.timestamp) return; - uint timePassed = block.timestamp - dependantSideInfo.lastInterestUpdate; - uint newRewards = dependantSideInfo.totalStake * dependantSideConfig.interest * timePassed / BILLION / dependantSideConfig.interestRate; - - dependantSideInfo.totalRewards += newRewards; - dependantSideInfo.lastInterestUpdate = block.timestamp; - emit Interest(true, newRewards); - } - - function _stakeDependantSide(address user, uint amount) internal { - require(active, "Pool is not active"); - require(amount >= dependantSideConfig.minStakeValue, "Pool: stake value is too low"); - if (msg.value != 0) { - require(mainSideConfig.token == address(0), "Pool: does not accept native coin"); - require(msg.value == amount, "Pool: wrong amount of native coin"); - } else { - SafeERC20.safeTransferFrom(IERC20(dependantSideConfig.token), msg.sender, address(this), amount); - } - - console.log("Staking dependant side"); - console.log("max user stake: ", _maxUserStakeValue(msg.sender)); - console.log("amount: ", amount); - - uint rewardsAmount = _calcRewards(true, amount); - - dependantSideStakers[msg.sender].stake += amount; - dependantSideInfo.totalStake += amount; - if (dependantSideStakers[msg.sender].stakedAt == 0) - dependantSideStakers[msg.sender].stakedAt = block.timestamp; - - require(dependantSideStakers[msg.sender].stake <= _maxUserStakeValue(msg.sender), "Pool: user max stake value exceeded"); - require(dependantSideInfo.totalStake <= dependantSideConfig.maxTotalStakeValue, "Pool: max stake value exceeded"); - require(dependantSideStakers[msg.sender].stake <= dependantSideConfig.maxStakePerUserValue, "Pool: max stake per user exceeded"); - - dependantSideInfo.totalRewards += rewardsAmount; - - _updateRewardsDebt(true, user, _calcRewards(true, dependantSideStakers[user].stake)); - emit StakeChanged(true, msg.sender, amount); - } - - function _unstakeDependantSide(address user, uint amount) internal { + function unstakeDependantSide(uint amount) public { require(dependantSideStakers[msg.sender].stake >= amount, "Not enough stake"); require(block.timestamp - dependantSideStakers[msg.sender].stakedAt >= dependantSideConfig.stakeLockPeriod, "Stake is locked"); - uint rewardsAmount = _calcRewards(true, amount); + uint rewardsAmount = _calcRewardsDependantSide(amount); dependantSideStakers[msg.sender].stake -= amount; dependantSideInfo.totalStake -= amount; @@ -435,7 +294,7 @@ contract DoubleSidePool is Initializable, AccessControl, IOnBlockListener { if (dependantSideStakers[msg.sender].stake == 0) dependantSideStakers[msg.sender].stakedAt = 0; dependantSideInfo.totalRewards -= rewardsAmount; - _updateRewardsDebt(true, user, _calcRewards(true, dependantSideStakers[user].stake)); + _updateRewardsDebtDependantSide(msg.sender, _calcRewardsDependantSide(dependantSideStakers[msg.sender].stake)); // cancel previous lock (if exists). canceledAmount will be added to new lock uint canceledAmount; @@ -458,18 +317,42 @@ contract DoubleSidePool is Initializable, AccessControl, IOnBlockListener { } - _claimRewards(true, msg.sender); + _claimRewardsDependantSide(msg.sender); emit UnstakeLocked(true, msg.sender, amount + canceledAmount, block.timestamp + mainSideConfig.lockPeriod, block.timestamp); emit StakeChanged(true, msg.sender, dependantSideStakers[msg.sender].stake); } - - function _unstakeFastDependantSide(address user, uint amount) internal { + + function unstakeFastMainSide(uint amount) public { + require(mainSideStakers[msg.sender].stake >= amount, "Not enough stake"); + + uint rewardsAmount = _calcRewardsMainSide(amount); + + mainSideStakers[msg.sender].stake -= amount; + mainSideInfo.totalStake -= amount; + + mainSideInfo.totalRewards -= rewardsAmount; + _updateRewardsDebtMainSide(msg.sender, _calcRewardsMainSide(mainSideStakers[msg.sender].stake)); + + uint penalty = amount * mainSideConfig.fastUnstakePenalty / BILLION; + if (mainSideConfig.token == address(0)) { + payable(msg.sender).transfer(amount - penalty); + } else { + SafeERC20.safeTransfer(IERC20(mainSideConfig.token), msg.sender, amount - penalty); + } + + _claimRewardsMainSide(msg.sender); + + emit UnstakeFast(false, msg.sender, amount, penalty); + emit StakeChanged(false, msg.sender, amount); + } + + function unstakeFastDependantSide(uint amount) public { require(dependantSideStakers[msg.sender].stake >= amount, "Not enough stake"); require(block.timestamp - dependantSideStakers[msg.sender].stakedAt >= dependantSideConfig.stakeLockPeriod, "Stake is locked"); - uint rewardsAmount = _calcRewards(true, amount); + uint rewardsAmount = _calcRewardsDependantSide(amount); dependantSideStakers[msg.sender].stake -= amount; dependantSideInfo.totalStake -= amount; @@ -477,7 +360,7 @@ contract DoubleSidePool is Initializable, AccessControl, IOnBlockListener { if (dependantSideStakers[msg.sender].stake == 0) dependantSideStakers[msg.sender].stakedAt = 0; dependantSideInfo.totalRewards -= rewardsAmount; - _updateRewardsDebt(true, user, _calcRewards(true, dependantSideStakers[user].stake)); + _updateRewardsDebtDependantSide(msg.sender, _calcRewardsDependantSide(dependantSideStakers[msg.sender].stake)); uint penalty = amount * dependantSideConfig.fastUnstakePenalty / BILLION; if (dependantSideConfig.token == address(0)) { @@ -486,90 +369,164 @@ contract DoubleSidePool is Initializable, AccessControl, IOnBlockListener { SafeERC20.safeTransfer(IERC20(dependantSideConfig.token), msg.sender, amount - penalty); } - _claimRewards(true, msg.sender); + _claimRewardsDependantSide(msg.sender); emit UnstakeFast(true, msg.sender, amount, penalty); emit StakeChanged(true, msg.sender, amount); } + function claimMainSide() public { + _calcClaimableRewardsMainSide(msg.sender); + _claimRewardsMainSide(msg.sender); + } + + function claimDependantSide() public { + _calcClaimableRewardsDependantSide(msg.sender); + _claimRewardsDependantSide(msg.sender); + } + + function onBlock() external { + _addInterestMainSide(); + _addInterestDependantSide(); + } + + // VIEW METHODS + + function getMainSideConfig() public view returns (MainSideConfig memory) { + return mainSideConfig; + } + + function getMainSideInfo() public view returns (SideInfo memory) { + return mainSideInfo; + } + + function getMainSideStaker(address user) public view returns (SideStaker memory) { + return mainSideStakers[user]; + } + + function getDependantSideConfig() public view returns (DependantSideConfig memory) { + return dependantSideConfig; + } + + function getDependantSideInfo() public view returns (SideInfo memory) { + return dependantSideInfo; + } + + function getDependantSideStaker(address user) public view returns (SideStaker memory) { + return dependantSideStakers[user]; + } + + function getUserMainSideRewards(address user) public view returns (uint) { + uint rewardsAmount = _calcRewardsMainSide(mainSideStakers[user].stake); + if (rewardsAmount + mainSideStakers[user].claimableRewards <= mainSideStakers[user].rewardsDebt) + return 0; + + return rewardsAmount + mainSideStakers[user].claimableRewards - mainSideStakers[user].rewardsDebt; + } + + function getUserDependantSideRewards(address user) public view returns (uint) { + uint rewardsAmount = _calcRewardsDependantSide(dependantSideStakers[user].stake); + if (rewardsAmount + dependantSideStakers[user].claimableRewards <= dependantSideStakers[user].rewardsDebt) + return 0; + + return rewardsAmount + dependantSideStakers[user].claimableRewards - dependantSideStakers[user].rewardsDebt; + } + + // INTERNAL METHODS + + function _addInterestMainSide() internal { + uint timePassed = block.timestamp - mainSideInfo.lastInterestUpdate; + uint newRewards = mainSideInfo.totalStake * mainSideConfig.interest * timePassed / BILLION / mainSideConfig.interestRate; + + mainSideInfo.totalRewards += newRewards; + mainSideInfo.lastInterestUpdate = block.timestamp; + emit Interest(false, newRewards); + } + + function _addInterestDependantSide() internal { + if (!hasSecondSide) return; + if (dependantSideInfo.lastInterestUpdate + dependantSideConfig.interestRate > block.timestamp) return; + uint timePassed = block.timestamp - dependantSideInfo.lastInterestUpdate; + uint newRewards = dependantSideInfo.totalStake * dependantSideConfig.interest * timePassed / BILLION / dependantSideConfig.interestRate; + + dependantSideInfo.totalRewards += newRewards; + dependantSideInfo.lastInterestUpdate = block.timestamp; + emit Interest(true, newRewards); + } + function _maxUserStakeValue(address user) internal view returns (uint) { - console.log("main side stake: ", mainSideStakers[user].stake); - console.log("stake limits multiplier: ", dependantSideConfig.stakeLimitsMultiplier); return mainSideStakers[user].stake * dependantSideConfig.stakeLimitsMultiplier; } - //COMMON METHODS - // store claimable rewards - function _calcClaimableRewards(bool dependant, address user) internal { - if (dependant) { - uint rewardsAmount = _calcRewards(dependant, dependantSideStakers[user].stake); - uint rewardsWithoutDebt = rewardsAmount - dependantSideStakers[user].rewardsDebt; - dependantSideStakers[user].claimableRewards += rewardsWithoutDebt; - dependantSideInfo.totalRewardsDebt += rewardsWithoutDebt; - dependantSideStakers[user].rewardsDebt += rewardsWithoutDebt; - } else { - uint rewardsAmount = _calcRewards(dependant, mainSideStakers[user].stake); - uint rewardsWithoutDebt = rewardsAmount - mainSideStakers[user].rewardsDebt; - mainSideStakers[user].claimableRewards += rewardsWithoutDebt; - mainSideInfo.totalRewardsDebt += rewardsWithoutDebt; - mainSideStakers[user].rewardsDebt += rewardsWithoutDebt; - } + function _calcClaimableRewardsMainSide(address user) internal { + uint rewardsAmount = _calcRewardsMainSide(mainSideStakers[user].stake); + uint rewardsWithoutDebt = rewardsAmount - mainSideStakers[user].rewardsDebt; + mainSideStakers[user].claimableRewards += rewardsWithoutDebt; + mainSideInfo.totalRewardsDebt += rewardsWithoutDebt; + mainSideStakers[user].rewardsDebt += rewardsWithoutDebt; } - function _claimRewards(bool dependant, address user) internal { - if (dependant) { - uint amount = dependantSideStakers[user].claimableRewards; - if (amount == 0) return; - - dependantSideStakers[user].claimableRewards = 0; - - uint rewardTokenAmount = amount * dependantSideConfig.rewardTokenPrice; - if (dependantSideConfig.rewardToken == address(0)) { - rewardsBank.withdrawAmb(payable(user), amount); - } else { - rewardsBank.withdrawErc20(dependantSideConfig.rewardToken, payable(user), rewardTokenAmount); - } - emit Claim(true, user, rewardTokenAmount); - } else { - uint amount = mainSideStakers[user].claimableRewards; - if (amount == 0) return; - - mainSideStakers[user].claimableRewards = 0; - - uint rewardTokenAmount = amount * mainSideConfig.rewardTokenPrice; - if (mainSideConfig.rewardToken == address(0)) { - rewardsBank.withdrawAmb(payable(user), amount); - } else { - rewardsBank.withdrawErc20(mainSideConfig.rewardToken, payable(user), rewardTokenAmount); - } - emit Claim(false, user, rewardTokenAmount); - } + function _calcClaimableRewardsDependantSide(address user) internal { + uint rewardsAmount = _calcRewardsDependantSide(dependantSideStakers[user].stake); + uint rewardsWithoutDebt = rewardsAmount - dependantSideStakers[user].rewardsDebt; + dependantSideStakers[user].claimableRewards += rewardsWithoutDebt; + dependantSideInfo.totalRewardsDebt += rewardsWithoutDebt; + dependantSideStakers[user].rewardsDebt += rewardsWithoutDebt; } - function _calcRewards(bool dependant, uint amount) internal view returns (uint) { - if (dependant) { - if (dependantSideInfo.totalStake == 0 && dependantSideInfo.totalRewards == 0) return amount; - return amount * dependantSideInfo.totalRewards / dependantSideInfo.totalStake; + function _claimRewardsMainSide(address user) internal { + uint amount = mainSideStakers[user].claimableRewards; + if (amount == 0) return; + + mainSideStakers[user].claimableRewards = 0; + + uint rewardTokenAmount = amount * mainSideConfig.rewardTokenPrice; + if (mainSideConfig.rewardToken == address(0)) { + rewardsBank.withdrawAmb(payable(user), amount); } else { - if (mainSideInfo.totalStake == 0 && mainSideInfo.totalRewards == 0) return amount; - return amount * mainSideInfo.totalRewards / mainSideInfo.totalStake; + rewardsBank.withdrawErc20(mainSideConfig.rewardToken, payable(user), rewardTokenAmount); } + emit Claim(false, user, rewardTokenAmount); } + function _claimRewardsDependantSide(address user) internal { + uint amount = dependantSideStakers[user].claimableRewards; + if (amount == 0) return; - function _updateRewardsDebt(bool dependant, address user, uint newDebt) internal { - if (dependant) { - uint oldDebt = dependantSideStakers[user].rewardsDebt; - if (newDebt < oldDebt) dependantSideInfo.totalRewardsDebt -= oldDebt - newDebt; - else dependantSideInfo.totalRewardsDebt += newDebt - oldDebt; - dependantSideStakers[user].rewardsDebt = newDebt; - } else { - uint oldDebt = mainSideStakers[user].rewardsDebt; - if (newDebt < oldDebt) mainSideInfo.totalRewardsDebt -= oldDebt - newDebt; - else mainSideInfo.totalRewardsDebt += newDebt - oldDebt; - mainSideStakers[user].rewardsDebt = newDebt; - } + dependantSideStakers[user].claimableRewards = 0; + + uint rewardTokenAmount = amount * dependantSideConfig.rewardTokenPrice; + if (dependantSideConfig.rewardToken == address(0)) { + rewardsBank.withdrawAmb(payable(user), amount); + } else { + rewardsBank.withdrawErc20(dependantSideConfig.rewardToken, payable(user), rewardTokenAmount); + } + emit Claim(true, user, rewardTokenAmount); + } + + function _calcRewardsMainSide(uint amount) internal view returns (uint) { + if (mainSideInfo.totalStake == 0 && mainSideInfo.totalRewards == 0) return amount; + return amount * mainSideInfo.totalRewards / mainSideInfo.totalStake; + } + + function _calcRewardsDependantSide(uint amount) internal view returns (uint) { + if (dependantSideInfo.totalStake == 0 && dependantSideInfo.totalRewards == 0) return amount; + return amount * dependantSideInfo.totalRewards / dependantSideInfo.totalStake; + } + + function _updateRewardsDebtMainSide(address user, uint newDebt) internal { + uint oldDebt = mainSideStakers[user].rewardsDebt; + if (newDebt < oldDebt) mainSideInfo.totalRewardsDebt -= oldDebt - newDebt; + else mainSideInfo.totalRewardsDebt += newDebt - oldDebt; + mainSideStakers[user].rewardsDebt = newDebt; + } + + function _updateRewardsDebtDependantSide(address user, uint newDebt) internal { + uint oldDebt = dependantSideStakers[user].rewardsDebt; + if (newDebt < oldDebt) dependantSideInfo.totalRewardsDebt -= oldDebt - newDebt; + else dependantSideInfo.totalRewardsDebt += newDebt - oldDebt; + dependantSideStakers[user].rewardsDebt = newDebt; } function _addressToString(address x) internal pure returns (string memory) { diff --git a/test/staking/token/DoubleSidePool.ts b/test/staking/token/DoubleSidePool.ts index 2d6713a..c496748 100644 --- a/test/staking/token/DoubleSidePool.ts +++ b/test/staking/token/DoubleSidePool.ts @@ -139,7 +139,7 @@ describe("DoubleSidePool", function () { it("Should allow staking on the main side", async function () { const stake = ethers.utils.parseEther("1000"); - await doubleSidePool.stake(false, stake); + await doubleSidePool.stakeMainSide(stake); const info = await doubleSidePool.mainSideInfo(); expect(info.totalStake).to.equal(stake); const staker = await doubleSidePool.getMainSideStaker(owner.address); @@ -148,11 +148,11 @@ describe("DoubleSidePool", function () { it("Should not allow staking when pool is deactivated", async function () { await doubleSidePool.deactivate(); - await expect(doubleSidePool.stake(false, 1000)).to.be.revertedWith("Pool is not active"); + await expect(doubleSidePool.stakeMainSide(1000)).to.be.revertedWith("Pool is not active"); }); it("Should not allow staking below minimum stake value", async function () { - await expect(doubleSidePool.stake(false, 1)).to.be.revertedWith("Pool: stake value is too low"); + await expect(doubleSidePool.stakeMainSide(1)).to.be.revertedWith("Pool: stake value is too low"); }); }); @@ -161,14 +161,14 @@ describe("DoubleSidePool", function () { beforeEach(async function () { await mainToken.approve(doubleSidePool.address, ethers.utils.parseEther("1000000")); - await doubleSidePool.stake(false, stake); + await doubleSidePool.stakeMainSide(stake); }); it("Should allow unstaking with rewards", async function () { await time.increase(D1); await doubleSidePool.onBlock(); - await expect(doubleSidePool.unstake(false, stake)).to.emit(lockKeeper, "Locked"); + await expect(doubleSidePool.unstakeMainSide(stake)).to.emit(lockKeeper, "Locked"); const info = await doubleSidePool.mainSideInfo(); expect(info.totalStake).to.equal(0); const staker = await doubleSidePool.getMainSideStaker(owner.address); @@ -180,18 +180,18 @@ describe("DoubleSidePool", function () { await doubleSidePool.onBlock(); const balanceBefore = await mainToken.balanceOf(owner.address); - await doubleSidePool.unstakeFast(false, stake); + await doubleSidePool.unstakeFastMainSide(stake); const balanceAfter = await mainToken.balanceOf(owner.address); expect(balanceAfter.sub(balanceBefore)).to.equal(stake.mul(90).div(100)); // 90% due to 10% penalty }); it("Should not allow unstaking more than staked", async function () { - await expect(doubleSidePool.unstake(false, stake.mul(2))).to.be.revertedWith("Not enough stake"); + await expect(doubleSidePool.unstakeMainSide(stake.mul(2))).to.be.revertedWith("Not enough stake"); }); it("Should allow unstaking when pool is deactivated", async function () { await doubleSidePool.deactivate(); - await expect(doubleSidePool.unstake(false, stake)).to.emit(lockKeeper, "Locked"); + await expect(doubleSidePool.unstakeMainSide(stake)).to.emit(lockKeeper, "Locked"); }); }); @@ -202,7 +202,7 @@ describe("DoubleSidePool", function () { }); it("Should allow claiming rewards", async function () { - await doubleSidePool.stake(false, 1000); + await doubleSidePool.stakeMainSide(1000); await time.increase(D1); await doubleSidePool.onBlock(); @@ -213,13 +213,13 @@ describe("DoubleSidePool", function () { expect(rewards).to.equal(expectedReward); const balanceBefore = await mainToken.balanceOf(owner.address); - await doubleSidePool.claim(false); + await doubleSidePool.claimMainSide(); const balanceAfter = await mainToken.balanceOf(owner.address); expect(balanceAfter.sub(balanceBefore)).to.equal(expectedReward); }); it("Should allow claiming rewards when pool is deactivated", async function () { - await doubleSidePool.stake(false, 1000); + await doubleSidePool.stakeMainSide(1000); await time.increase(D1); await doubleSidePool.onBlock(); @@ -231,7 +231,7 @@ describe("DoubleSidePool", function () { expect(rewards).to.equal(expectedReward); const balanceBefore = await mainToken.balanceOf(owner.address); - await doubleSidePool.claim(false); + await doubleSidePool.claimMainSide(); const balanceAfter = await mainToken.balanceOf(owner.address); expect(balanceAfter.sub(balanceBefore)).to.equal(expectedReward); }); @@ -264,10 +264,10 @@ describe("DoubleSidePool", function () { it("Should allow staking on the dependant side", async function () { const mainStake = 100000; - await doubleSidePool.stake(false, mainStake); + await doubleSidePool.stakeMainSide(mainStake); const dependantStake = 100; - await doubleSidePool.stake(true, dependantStake); + await doubleSidePool.stakeDependantSide(dependantStake); const info = await doubleSidePool.dependantSideInfo(); expect(info.totalStake).to.equal(dependantStake); @@ -277,24 +277,24 @@ describe("DoubleSidePool", function () { it("Should not allow staking on dependant side beyond the limit", async function () { const mainStake = 1000; - await doubleSidePool.stake(false, mainStake); + await doubleSidePool.stakeMainSide( mainStake); const dependantStake = ethers.utils.parseEther("2001"); // Exceeds 2x main stake - await expect(doubleSidePool.stake(true, dependantStake)).to.be.revertedWith("Pool: user max stake value exceeded"); + await expect(doubleSidePool.stakeDependantSide(dependantStake)).to.be.revertedWith("Pool: user max stake value exceeded"); }); it("Should allow unstaking from the dependant side", async function () { await doubleSidePool.setStakeLockPeriod(0); const mainStake = 1000; - await doubleSidePool.stake(false, mainStake); + await doubleSidePool.stakeMainSide(mainStake); const dependantStake = 100; - await doubleSidePool.stake(true, dependantStake); + await doubleSidePool.stakeDependantSide(dependantStake); await time.increase(D1); await doubleSidePool.onBlock(); - await expect(doubleSidePool.unstake(true, dependantStake)).to.emit(lockKeeper, "Locked"); + await expect(doubleSidePool.unstakeDependantSide(dependantStake)).to.emit(lockKeeper, "Locked"); const info = await doubleSidePool.dependantSideInfo(); expect(info.totalStake).to.equal(0); const staker = await doubleSidePool.getDependantSideStaker(owner.address); @@ -303,10 +303,10 @@ describe("DoubleSidePool", function () { it("Should allow claiming rewards from the dependant side", async function () { const mainStake = 1000; - await doubleSidePool.stake(false, mainStake); + await doubleSidePool.stakeMainSide( mainStake); const dependantStake = 100; - await doubleSidePool.stake(true, dependantStake); + await doubleSidePool.stakeDependantSide(dependantStake); await time.increase(D1); await doubleSidePool.onBlock(); @@ -316,7 +316,7 @@ describe("DoubleSidePool", function () { expect(rewards).to.equal(expectedReward); const balanceBefore = await dependantToken.balanceOf(owner.address); - await doubleSidePool.claim(true); + await doubleSidePool.claimDependantSide(); const balanceAfter = await dependantToken.balanceOf(owner.address); expect(balanceAfter.sub(balanceBefore)).to.equal(expectedReward); }); @@ -324,37 +324,37 @@ describe("DoubleSidePool", function () { it("Should not allow staking on dependant side when total stake limit is reached", async function () { await doubleSidePool.setMaxTotalStakeValue(1000); const mainStake = 100000; // Set a high main stake to avoid individual limit - await doubleSidePool.stake(false, mainStake); + await doubleSidePool.stakeMainSide(mainStake); const maxStake = 1000; - await doubleSidePool.stake(true, maxStake); + await doubleSidePool.stakeDependantSide(maxStake); - await expect(doubleSidePool.stake(true, 10)).to.be.revertedWith("Pool: max stake value exceeded"); + await expect(doubleSidePool.stakeDependantSide(10)).to.be.revertedWith("Pool: max stake value exceeded"); }); it("Should not allow unstaking from dependant side before stake lock period", async function () { const mainStake = 1000; - await doubleSidePool.stake(false, mainStake); + await doubleSidePool.stakeMainSide(mainStake); const dependantStake = 100; - await doubleSidePool.stake(true, dependantStake); + await doubleSidePool.stakeDependantSide(dependantStake); - await expect(doubleSidePool.unstake(true, dependantStake)).to.be.revertedWith("Stake is locked"); + await expect(doubleSidePool.unstakeDependantSide(dependantStake)).to.be.revertedWith("Stake is locked"); }); it("Should allow fast unstaking from dependant side with penalty", async function () { await doubleSidePool.setStakeLockPeriod(0); const mainStake = 1000; - await doubleSidePool.stake(false, mainStake); + await doubleSidePool.stakeMainSide(mainStake); const dependantStake = 100; - await doubleSidePool.stake(true, dependantStake); + await doubleSidePool.stakeDependantSide(dependantStake); //await time.increase(D1); //await doubleSidePool.onBlock(); const balanceBefore = await dependantToken.balanceOf(owner.address); - await doubleSidePool.unstakeFast(true, dependantStake); + await doubleSidePool.unstakeFastDependantSide(dependantStake); const balanceAfter = await dependantToken.balanceOf(owner.address); const expectedReturn = 95; // 95% due to 5% penalty @@ -363,18 +363,18 @@ describe("DoubleSidePool", function () { it("Should update stake limits when main side stake changes", async function () { const initialMainStake = 1000; - await doubleSidePool.stake(false, initialMainStake); + await doubleSidePool.stakeMainSide(initialMainStake); const maxDependantStake = 2000; // 2x multiplier - await doubleSidePool.stake(true, maxDependantStake); + await doubleSidePool.stakeDependantSide(maxDependantStake); // Increase main stake const additionalMainStake = 100; - await doubleSidePool.stake(false, additionalMainStake); + await doubleSidePool.stakeMainSide(additionalMainStake); // Now we should be able to stake more on the dependant side const additionalDependantStake = 200; - await expect(doubleSidePool.stake(true, additionalDependantStake)).to.not.be.reverted; + await expect(doubleSidePool.stakeDependantSide(additionalDependantStake)).to.not.be.reverted; }); it("Should not allow adding dependant side twice", async function () { @@ -424,10 +424,10 @@ describe("DoubleSidePool", function () { it("Should correctly calculate rewards for both sides", async function () { const mainStake = 1000; - await doubleSidePool.stake(false, mainStake); + await doubleSidePool.stakeMainSide(mainStake); const dependantStake = 500; - await doubleSidePool.stake(true, dependantStake); + await doubleSidePool.stakeDependantSide(dependantStake); await time.increase(D1); await doubleSidePool.onBlock(); @@ -442,13 +442,13 @@ describe("DoubleSidePool", function () { it("Should allow staking and unstaking on both sides independently", async function () { await doubleSidePool.setStakeLockPeriod(0); const mainStake = ethers.utils.parseEther("1000"); - await doubleSidePool.stake(false, mainStake); + await doubleSidePool.stakeMainSide(mainStake); const dependantStake = ethers.utils.parseEther("500"); - await doubleSidePool.stake(true, dependantStake); + await doubleSidePool.stakeDependantSide(dependantStake); - await doubleSidePool.unstake(false, mainStake.div(2)); - await doubleSidePool.unstake(true, dependantStake.div(2)); + await doubleSidePool.unstakeMainSide(mainStake.div(2)); + await doubleSidePool.unstakeDependantSide(dependantStake.div(2)); const mainStaker = await doubleSidePool.getMainSideStaker(owner.address); const dependantStaker = await doubleSidePool.getDependantSideStaker(owner.address); @@ -459,20 +459,20 @@ describe("DoubleSidePool", function () { it("Should enforce dependant side limits based on main side stake", async function () { const mainStake = 1000; - await doubleSidePool.stake(false, mainStake); + await doubleSidePool.stakeMainSide(mainStake); const maxDependantStake = 2000; // 2x multiplier - await doubleSidePool.stake(true, maxDependantStake); + await doubleSidePool.stakeDependantSide(maxDependantStake); // Trying to stake more should fail - await expect(doubleSidePool.stake(true, 100)).to.be.revertedWith("Pool: user max stake value exceeded"); + await expect(doubleSidePool.stakeDependantSide(100)).to.be.revertedWith("Pool: user max stake value exceeded"); // Unstake half of main side await time.increase(D1); - await doubleSidePool.unstake(false, 500); + await doubleSidePool.unstakeMainSide(500); // Trying to stake on dependant side should still fail due to existing stake - await expect(doubleSidePool.stake(true, 100)).to.be.revertedWith("Pool: user max stake value exceeded"); + await expect(doubleSidePool.stakeDependantSide(100)).to.be.revertedWith("Pool: user max stake value exceeded"); }); }); @@ -500,24 +500,24 @@ describe("DoubleSidePool", function () { }); it("Should handle zero stakes correctly", async function () { - await expect(doubleSidePool.stake(false, 0)).to.be.revertedWith("Pool: stake value is too low"); - await expect(doubleSidePool.stake(true, 0)).to.be.revertedWith("Pool: stake value is too low"); + await expect(doubleSidePool.stakeMainSide(0)).to.be.revertedWith("Pool: stake value is too low"); + await expect(doubleSidePool.stakeDependantSide(0)).to.be.revertedWith("Pool: stake value is too low"); }); it("Should handle unstaking more than staked amount", async function () { const stake = ethers.utils.parseEther("100"); - await doubleSidePool.stake(false, stake); - await doubleSidePool.stake(true, stake); + await doubleSidePool.stakeMainSide(stake); + await doubleSidePool.stakeDependantSide(stake); await time.increase(D1); - await expect(doubleSidePool.unstake(false, stake.mul(2))).to.be.revertedWith("Not enough stake"); - await expect(doubleSidePool.unstake(true, stake.mul(2))).to.be.revertedWith("Not enough stake"); + await expect(doubleSidePool.unstakeMainSide(stake.mul(2))).to.be.revertedWith("Not enough stake"); + await expect(doubleSidePool.unstakeDependantSide(stake.mul(2))).to.be.revertedWith("Not enough stake"); }); it("Should handle claiming rewards when there are no rewards", async function () { - await doubleSidePool.claim(false); - await doubleSidePool.claim(true); + await doubleSidePool.claimMainSide(); + await doubleSidePool.claimDependantSide(); // These should not revert, but also should not transfer any tokens }); @@ -527,18 +527,18 @@ describe("DoubleSidePool", function () { const stake2 = 200; const stake3 = 300; - await doubleSidePool.stake(false, stake1); - await doubleSidePool.stake(true, stake1); + await doubleSidePool.stakeMainSide(stake1); + await doubleSidePool.stakeDependantSide(stake1); await time.increase(D1 / 2); - await doubleSidePool.stake(false, stake2); - await doubleSidePool.stake(true, stake2); + await doubleSidePool.stakeMainSide(stake2); + await doubleSidePool.stakeDependantSide(stake2); await time.increase(D1 / 2); - await doubleSidePool.unstake(false, stake3); - await doubleSidePool.unstake(true, stake3); + await doubleSidePool.unstakeMainSide(stake3); + await doubleSidePool.unstakeDependantSide(stake3); const mainStaker = await doubleSidePool.getMainSideStaker(owner.address); const dependantStaker = await doubleSidePool.getDependantSideStaker(owner.address);