diff --git a/.gas-report b/.gas-report index 7179b6a..a43cca3 100644 --- a/.gas-report +++ b/.gas-report @@ -22,17 +22,18 @@ | MIN_LOCKUP_PERIOD | 275 | 275 | 275 | 275 | 11 | | MP_RATE_PER_YEAR | 231 | 231 | 231 | 231 | 3 | | SCALE_FACTOR | 295 | 295 | 295 | 295 | 41 | -| STAKING_TOKEN | 273 | 273 | 273 | 273 | 172 | +| STAKING_TOKEN | 273 | 273 | 273 | 273 | 174 | | accountedRewards | 351 | 906 | 351 | 2351 | 72 | | emergencyModeEnabled | 2377 | 2377 | 2377 | 2377 | 7 | | enableEmergencyMode | 23504 | 40411 | 45696 | 45696 | 8 | | getAccount | 1596 | 1596 | 1596 | 1596 | 71 | -| isTrustedCodehash | 496 | 996 | 496 | 2496 | 172 | +| getStakedBalance | 2579 | 2579 | 2579 | 2579 | 1 | +| isTrustedCodehash | 496 | 1013 | 496 | 2496 | 174 | | rewardIndex | 373 | 400 | 373 | 2373 | 72 | -| setTrustedCodehash | 47926 | 47926 | 47926 | 47926 | 43 | +| setTrustedCodehash | 47926 | 47926 | 47926 | 47926 | 45 | | totalMP | 330 | 330 | 330 | 330 | 75 | | totalMaxMP | 351 | 351 | 351 | 351 | 75 | -| totalStaked | 330 | 330 | 330 | 330 | 75 | +| totalStaked | 330 | 330 | 330 | 330 | 76 | | updateAccountMP | 36758 | 38996 | 39260 | 39260 | 19 | | updateGlobalState | 32134 | 60366 | 49513 | 82460 | 28 | @@ -42,10 +43,12 @@ | Deployment Cost | Deployment Size | | | | | | 1095864 | 5202 | | | | | | Function Name | min | avg | median | max | # calls | +| STAKING_TOKEN | 217 | 217 | 217 | 217 | 1 | | emergencyExit | 31410 | 43924 | 43160 | 60260 | 7 | | lock | 38362 | 60516 | 42741 | 100445 | 3 | -| stake | 199213 | 236948 | 242906 | 263435 | 55 | +| stake | 199213 | 237055 | 242906 | 263435 | 56 | | unstake | 84988 | 113999 | 103434 | 146128 | 13 | +| withdraw | 37318 | 37318 | 37318 | 37318 | 1 | | src/XPNFTToken.sol:XPNFTToken contract | | | | | | @@ -121,9 +124,9 @@ | Deployment Cost | Deployment Size | | | | | | 639406 | 3369 | | | | | | Function Name | min | avg | median | max | # calls | -| approve | 46334 | 46343 | 46346 | 46346 | 220 | -| balanceOf | 561 | 1381 | 561 | 2561 | 334 | -| mint | 51284 | 58817 | 51284 | 68384 | 236 | +| approve | 46334 | 46343 | 46346 | 46346 | 222 | +| balanceOf | 561 | 1382 | 561 | 2561 | 336 | +| mint | 51284 | 58898 | 51284 | 68384 | 238 | | transfer | 34390 | 48859 | 51490 | 51490 | 13 | diff --git a/.gas-snapshot b/.gas-snapshot index 94d93e7..6cd0596 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -29,6 +29,7 @@ StakeTest:test_StakeOneAccountReachingMPLimit() (gas: 494078) StakeTest:test_StakeOneAccountWithMaxLockUp() (gas: 298175) StakeTest:test_StakeOneAccountWithMinLockUp() (gas: 298187) StakeTest:test_StakeOneAccountWithRandomLockUp() (gas: 298298) +StakingTokenTest:testStakeToken() (gas: 10426) UnstakeTest:test_StakeMultipleAccounts() (gas: 493323) UnstakeTest:test_StakeMultipleAccountsAndRewards() (gas: 640807) UnstakeTest:test_StakeMultipleAccountsMPIncreasesMaxMPDoesNotChange() (gas: 818251) @@ -48,6 +49,7 @@ UnstakeTest:test_UnstakeOneAccount() (gas: 480152) UnstakeTest:test_UnstakeOneAccountAndAccruedMP() (gas: 496638) UnstakeTest:test_UnstakeOneAccountAndRewards() (gas: 585964) UnstakeTest:test_UnstakeOneAccountWithLockUpAndAccruedMP() (gas: 518574) +WithdrawTest:test_CannotWithdrawStakedFunds() (gas: 295608) XPNFTTokenTest:testApproveNotAllowed() (gas: 10507) XPNFTTokenTest:testGetApproved() (gas: 10531) XPNFTTokenTest:testIsApprovedForAll() (gas: 10705) diff --git a/src/StakeVault.sol b/src/StakeVault.sol index efb0322..67d462b 100644 --- a/src/StakeVault.sol +++ b/src/StakeVault.sol @@ -13,7 +13,7 @@ import { IStakeManager } from "./interfaces/IStakeManager.sol"; * @dev This contract is owned by the user and allows staking, unstaking, and withdrawing tokens. */ contract StakeVault is Ownable { - error StakeVault__NoEnoughAvailableBalance(); + error StakeVault__NotEnoughAvailableBalance(); error StakeVault__InvalidDestinationAddress(); error StakeVault__UpdateNotAvailable(); error StakeVault__StakingFailed(); @@ -156,7 +156,7 @@ contract StakeVault is Ownable { function _withdraw(IERC20 _token, uint256 _amount, address _destination) internal { if (_token == STAKING_TOKEN && STAKING_TOKEN.balanceOf(address(this)) - amountStaked() < _amount) { - revert StakeVault__NoEnoughAvailableBalance(); + revert StakeVault__NotEnoughAvailableBalance(); } _token.transfer(_destination, _amount); } diff --git a/test/StakeVault.test.sol b/test/StakeVault.test.sol index ef4ba1d..6d21020 100644 --- a/test/StakeVault.test.sol +++ b/test/StakeVault.test.sol @@ -49,3 +49,23 @@ contract StakingTokenTest is StakeVaultTest { assertEq(address(stakeVault.STAKING_TOKEN()), address(stakingToken)); } } + +contract WithdrawTest is StakeVaultTest { + function setUp() public override { + StakeVaultTest.setUp(); + } + + function test_CannotWithdrawStakedFunds() public { + // first, stake some funds + vm.prank(alice); + stakeVault.stake(10e18, 0); + + assertEq(stakingToken.balanceOf(address(stakeVault)), 10e18); + assertEq(streamer.totalStaked(), 10e18); + + // try withdrawing funds without unstaking + vm.prank(alice); + vm.expectRevert(StakeVault.StakeVault__NotEnoughAvailableBalance.selector); + stakeVault.withdraw(stakingToken, 10e18); + } +}