Skip to content

Commit

Permalink
Merge pull request #476 from DistributedCollective/fix/staking_stake
Browse files Browse the repository at this point in the history
Fix/staking stake
  • Loading branch information
jameshowlett977 authored Jan 23, 2023
2 parents 3b06cca + 1f626bd commit 6c5446f
Show file tree
Hide file tree
Showing 4 changed files with 538 additions and 3 deletions.
8 changes: 5 additions & 3 deletions contracts/governance/Staking/modules/StakingStakeModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ contract StakingStakeModule is IFunctionsList, StakingShared, CheckpointsShared,
uint256 until,
address stakeFor,
address delegatee
) external whenNotPaused {
_notSameBlockAsStakingCheckpoint(until); // must wait a block before staking again for that same deadline
) external whenNotPaused whenNotFrozen {
_stake(msg.sender, amount, until, stakeFor, delegatee, false);
}

Expand Down Expand Up @@ -128,6 +127,8 @@ contract StakingStakeModule is IFunctionsList, StakingShared, CheckpointsShared,
if (stakeFor == address(0)) {
stakeFor = sender;
}
// must wait a block before staking again for that same deadline
_notSameBlockAsStakingCheckpoint(until, stakeFor);

/// @dev Delegate for stakeFor if not specified otherwise.
if (delegatee == address(0)) {
Expand All @@ -154,11 +155,12 @@ contract StakingStakeModule is IFunctionsList, StakingShared, CheckpointsShared,
// @dev only the user that stakes for himself is allowed to delegate VP to another address
// which works with vesting stakes and prevents vulnerability of delegating VP to an arbitrary address from
// any address
if (delegatee != stakeFor)
if (delegatee != stakeFor) {
require(
stakeFor == sender,
"Only stakeFor account is allowed to change delegatee"
);
}

/// @dev Update delegatee.
delegates[stakeFor][until] = delegatee;
Expand Down
8 changes: 8 additions & 0 deletions contracts/governance/Staking/modules/shared/StakingShared.sol
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ contract StakingShared is StakingStorageShared, SafeMath96 {
// abstract
}

//SHOULDN'T BE USED, CAN BE EASILY BROKEN USING CONTRACT
function _notSameBlockAsStakingCheckpoint(uint256 lockDate) internal view {
uint32 nCheckpoints = numUserStakingCheckpoints[msg.sender][lockDate];
bool notSameBlock =
Expand All @@ -78,6 +79,13 @@ contract StakingShared is StakingStorageShared, SafeMath96 {
require(notSameBlock, "cannot be mined in the same block as last stake"); // S20
}

function _notSameBlockAsStakingCheckpoint(uint256 lockDate, address stakeFor) internal view {
uint32 nCheckpoints = numUserStakingCheckpoints[stakeFor][lockDate];
bool notSameBlock =
userStakingCheckpoints[stakeFor][lockDate][nCheckpoints - 1].fromBlock != block.number;
require(notSameBlock, "cannot be mined in the same block as last stake"); // S20
}

/**
* @notice Unstaking is possible every 2 weeks only. This means, to
* calculate the key value for the staking checkpoints, we need to
Expand Down
30 changes: 30 additions & 0 deletions contracts/mockup/modules/StakingWrapperMockup.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
pragma solidity ^0.5.17;
pragma experimental ABIEncoderV2;

import "../../governance/Staking/interfaces/IStaking.sol";
import "../../interfaces/IERC20.sol";

import "hardhat/console.sol";

contract StakingWrapperMockup {
IStaking staking;
IERC20 token;

constructor(IStaking _staking, IERC20 _token) public {
staking = _staking;
token = _token;
}

function stake2times(
uint96 amount,
uint256 until,
address stakeFor,
address delegatee
) external {
require(token.transferFrom(msg.sender, address(this), amount * 2));
token.approve(address(staking), amount * 2);

staking.stake(amount, until, stakeFor, delegatee);
staking.stake(amount, until, stakeFor, delegatee);
}
}
Loading

0 comments on commit 6c5446f

Please sign in to comment.