Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.

Commit

Permalink
Merge pull request #345 from maticnetwork/pre-upgrade
Browse files Browse the repository at this point in the history
Pre upgrade
  • Loading branch information
jdkanani committed Feb 17, 2021
2 parents 3874b5b + 43d77c9 commit b6e7800
Show file tree
Hide file tree
Showing 16 changed files with 151 additions and 82 deletions.
5 changes: 4 additions & 1 deletion contracts/root/IRootChain.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ pragma solidity ^0.5.2;
interface IRootChain {
function slash() external;

function submitHeaderBlock(bytes calldata data, uint[3][] calldata sigs)
function submitHeaderBlock(bytes calldata data, bytes calldata sigs)
external;

function submitCheckpoint(bytes calldata data, uint[3][] calldata sigs)
external;

function getLastChildBlock() external view returns (uint256);
Expand Down
6 changes: 5 additions & 1 deletion contracts/root/RootChain.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ contract RootChain is RootChainStorage, IRootChain {
_;
}

function submitHeaderBlock(bytes calldata data, uint[3][] calldata sigs) external {
function submitHeaderBlock(bytes calldata data, bytes calldata sigs) external {
revert();
}

function submitCheckpoint(bytes calldata data, uint[3][] calldata sigs) external {
(address proposer, uint256 start, uint256 end, bytes32 rootHash, bytes32 accountHash, uint256 _borChainID) = abi
.decode(data, (address, uint256, uint256, bytes32, bytes32, uint256));
require(CHAINID == _borChainID, "Invalid bor chain id");
Expand Down
20 changes: 20 additions & 0 deletions contracts/staking/EventsHub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ contract EventsHub is Initializable {
_;
}

modifier onlyStakeManager() {
require(registry.getStakeManagerAddress() == msg.sender,
"Invalid sender, not stake manager");
_;
}

function initialize(Registry _registry) external initializer {
registry = _registry;
}
Expand All @@ -48,4 +54,18 @@ contract EventsHub is Initializable {
) public onlyValidatorContract(validatorId) {
emit ShareBurnedWithId(validatorId, user, amount, tokens, burnId);
}

event RewardParams(
uint256 rewardDecreasePerCheckpoint,
uint256 maxRewardedCheckpoints,
uint256 checkpointRewardDelta
);

function logRewardParams(
uint256 rewardDecreasePerCheckpoint,
uint256 maxRewardedCheckpoints,
uint256 checkpointRewardDelta
) public onlyStakeManager {
emit RewardParams(rewardDecreasePerCheckpoint, maxRewardedCheckpoints, checkpointRewardDelta);
}
}
9 changes: 9 additions & 0 deletions contracts/staking/stakeManager/IStakeManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,13 @@ contract IStakeManager {
function withdrawDelegatorsReward(uint256 validatorId) public returns(uint256);

function delegatorsReward(uint256 validatorId) public view returns(uint256);

function dethroneAndStake(
address auctionUser,
uint256 heimdallFee,
uint256 validatorId,
uint256 auctionAmount,
bool acceptDelegation,
bytes calldata signerPubkey
) external;
}
70 changes: 36 additions & 34 deletions contracts/staking/stakeManager/StakeManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {StakeManagerStorage} from "./StakeManagerStorage.sol";
import {StakeManagerStorageExtension} from "./StakeManagerStorageExtension.sol";
import {IGovernance} from "../../common/governance/IGovernance.sol";
import {Initializable} from "../../common/mixin/Initializable.sol";
import {ValidatorAuction} from "./ValidatorAuction.sol";
import {StakeManagerExtension} from "./StakeManagerExtension.sol";

contract StakeManager is
StakeManagerStorage,
Expand Down Expand Up @@ -78,10 +78,10 @@ contract StakeManager is
address _validatorShareFactory,
address _governance,
address _owner,
address _auctionImplementation
address _extensionCode
) external initializer {
require(isContract(_auctionImplementation), "auction impl incorrect");
auctionImplementation = _auctionImplementation;
require(isContract(_extensionCode), "auction impl incorrect");
extensionCode = _extensionCode;
governance = IGovernance(_governance);
registry = _registry;
rootChain = _rootchain;
Expand Down Expand Up @@ -209,7 +209,7 @@ contract StakeManager is
}

function updateCheckPointBlockInterval(uint256 _blocks) public onlyGovernance {
require(_blocks != 0, "incorrect value");
require(_blocks != 0);
checkPointBlockInterval = _blocks;
}

Expand All @@ -221,29 +221,31 @@ contract StakeManager is

function updateCheckpointRewardParams(
uint256 _rewardDecreasePerCheckpoint,
uint256 _maxSkippedCheckpoints,
uint256 _maxRewardedCheckpoints,
uint256 _checkpointRewardDelta
) public onlyGovernance {
require(_maxSkippedCheckpoints.mul(_rewardDecreasePerCheckpoint) <= CHK_REWARD_PRECISION);
require(_checkpointRewardDelta <= CHK_REWARD_PRECISION);

rewardDecreasePerCheckpoint = _rewardDecreasePerCheckpoint;
maxSkippedCheckpoints = _maxSkippedCheckpoints;
checkpointRewardDelta = _checkpointRewardDelta;
delegatedFwd(
extensionCode,
abi.encodeWithSelector(
StakeManagerExtension(extensionCode).updateCheckpointRewardParams.selector,
_rewardDecreasePerCheckpoint,
_maxRewardedCheckpoints,
_checkpointRewardDelta
)
);
}

// New implementation upgrade

function migrateValidatorsData(uint256 validatorIdFrom, uint256 validatorIdTo) public onlyOwner {
for (uint256 i = validatorIdFrom; i < validatorIdTo; ++i) {
ValidatorShare contractAddress = ValidatorShare(validators[i].contractAddress);
if (contractAddress != ValidatorShare(0)) {
validators[i].delegatorsReward = contractAddress.validatorRewards_deprecated().add(INITIALIZED_AMOUNT);
validators[i].delegatedAmount = contractAddress.activeAmount_deprecated();
validators[i].commissionRate = contractAddress.commissionRate_deprecated();
validators[i].reward = validators[i].reward.add(INITIALIZED_AMOUNT);
}
}
delegatedFwd(
extensionCode,
abi.encodeWithSelector(
StakeManagerExtension(extensionCode).migrateValidatorsData.selector,
validatorIdFrom,
validatorIdTo
)
);
}

function insertSigners(address[] memory _signers) public onlyOwner {
Expand All @@ -254,7 +256,7 @@ contract StakeManager is
@dev Users must exit before this update or all funds may get lost
*/
function updateValidatorContractAddress(uint256 validatorId, address newContractAddress) public onlyGovernance {
require(IValidatorShare(newContractAddress).owner() == address(this), "Not stakeManager");
require(IValidatorShare(newContractAddress).owner() == address(this));
validators[validatorId].contractAddress = newContractAddress;
}

Expand Down Expand Up @@ -294,7 +296,7 @@ contract StakeManager is
uint256 amount
) external onlyGovernance {
address contractAddr = validators[validatorId].contractAddress;
require(contractAddr != address(0x0), "not validator");
require(contractAddr != address(0x0));
IValidatorShare(contractAddr).drain(tokenAddr, destination, amount);
}

Expand All @@ -306,10 +308,10 @@ contract StakeManager is
address _NFTContract,
address _stakingLogger,
address _validatorShareFactory,
address _auctionImplementation
address _extensionCode
) external onlyGovernance {
require(isContract(_auctionImplementation), "auction impl incorrect");
auctionImplementation = _auctionImplementation;
require(isContract(_extensionCode));
extensionCode = _extensionCode;
NFTContract = StakingNFT(_NFTContract);
logger = StakingInfo(_stakingLogger);
validatorShareFactory = ValidatorShareFactory(_validatorShareFactory);
Expand Down Expand Up @@ -353,9 +355,9 @@ contract StakeManager is
bytes calldata _signerPubkey
) external onlyWhenUnlocked {
delegatedFwd(
auctionImplementation,
extensionCode,
abi.encodeWithSelector(
ValidatorAuction(auctionImplementation).startAuction.selector,
StakeManagerExtension(extensionCode).startAuction.selector,
validatorId,
amount,
_acceptDelegation,
Expand All @@ -369,9 +371,9 @@ contract StakeManager is
uint256 heimdallFee /** for new validator */
) external onlyWhenUnlocked {
delegatedFwd(
auctionImplementation,
extensionCode,
abi.encodeWithSelector(
ValidatorAuction(auctionImplementation).confirmAuctionBid.selector,
StakeManagerExtension(extensionCode).confirmAuctionBid.selector,
validatorId,
heimdallFee,
address(this)
Expand All @@ -397,7 +399,7 @@ contract StakeManager is
}

function unstake(uint256 validatorId) external onlyStaker(validatorId) {
require(validatorAuction[validatorId].amount == 0, "Wait for auction completion");
require(validatorAuction[validatorId].amount == 0);

Status status = validators[validatorId].status;
require(
Expand Down Expand Up @@ -786,7 +788,7 @@ contract StakeManager is
uint256 amount,
uint256 deactivationEpoch,
uint256 _currentEpoch
) private view returns (bool) {
) private pure returns (bool) {
return (amount > 0 && (deactivationEpoch == 0 || deactivationEpoch > _currentEpoch) && status == Status.Active);
}

Expand Down Expand Up @@ -819,7 +821,7 @@ contract StakeManager is

uint256 targetBlockInterval = checkPointBlockInterval;
uint256 ckpReward = CHECKPOINT_REWARD;
uint256 fullIntervals = Math.min(blockInterval / targetBlockInterval, maxSkippedCheckpoints);
uint256 fullIntervals = Math.min(blockInterval / targetBlockInterval, maxRewardedCheckpoints);

// only apply to full checkpoints
if (fullIntervals > 0 && fullIntervals != prevBlockInterval) {
Expand Down Expand Up @@ -963,7 +965,7 @@ contract StakeManager is
uint256 validatorStakePower,
uint256 currentRewardPerStake,
uint256 initialRewardPerStake
) private returns (uint256) {
) private pure returns (uint256) {
uint256 eligibleReward = currentRewardPerStake - initialRewardPerStake;
return eligibleReward.mul(validatorStakePower).div(REWARD_PRECISION);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ import {IERC20} from "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
import {SafeMath} from "openzeppelin-solidity/contracts/math/SafeMath.sol";
import {Registry} from "../../common/Registry.sol";
import {GovernanceLockable} from "../../common/mixin/GovernanceLockable.sol";
import {RootChainable} from "../../common/mixin/RootChainable.sol";
import {StakingInfo} from "../StakingInfo.sol";
import {StakingNFT} from "./StakingNFT.sol";
import {StakeManager} from "./StakeManager.sol";
import {IStakeManager} from "./IStakeManager.sol";
import {StakeManagerStorage} from "./StakeManagerStorage.sol";
import {StakeManagerStorageExtension} from "./StakeManagerStorageExtension.sol";
import {Math} from "openzeppelin-solidity/contracts/math/Math.sol";
import {Initializable} from "../../common/mixin/Initializable.sol";
import {EventsHub} from "../EventsHub.sol";
import {ValidatorShare} from "../validatorShare/ValidatorShare.sol";

contract ValidatorAuction is StakeManagerStorage, Initializable, StakeManagerStorageExtension {
contract StakeManagerExtension is StakeManagerStorage, Initializable, StakeManagerStorageExtension {
using SafeMath for uint256;

constructor() public GovernanceLockable(address(0x0)) {}
Expand Down Expand Up @@ -82,7 +81,7 @@ contract ValidatorAuction is StakeManagerStorage, Initializable, StakeManagerSto
function confirmAuctionBid(
uint256 validatorId,
uint256 heimdallFee, /** for new validator */
StakeManager stakeManager
IStakeManager stakeManager
) external {
Auction storage auction = validatorAuction[validatorId];
address auctionUser = auction.user;
Expand Down Expand Up @@ -125,4 +124,41 @@ contract ValidatorAuction is StakeManagerStorage, Initializable, StakeManagerSto
delete validatorAuction[validatorId];
validatorAuction[validatorId].startEpoch = startEpoch;
}

function migrateValidatorsData(uint256 validatorIdFrom, uint256 validatorIdTo) external {
for (uint256 i = validatorIdFrom; i < validatorIdTo; ++i) {
ValidatorShare contractAddress = ValidatorShare(validators[i].contractAddress);
if (contractAddress != ValidatorShare(0)) {
validators[i].delegatorsReward = contractAddress.validatorRewards_deprecated().add(INITIALIZED_AMOUNT);
validators[i].delegatedAmount = contractAddress.activeAmount_deprecated();
validators[i].commissionRate = contractAddress.commissionRate_deprecated();
}

validators[i].reward = validators[i].reward.add(INITIALIZED_AMOUNT);
}
}

function updateCheckpointRewardParams(
uint256 _rewardDecreasePerCheckpoint,
uint256 _maxRewardedCheckpoints,
uint256 _checkpointRewardDelta
) external {
require(_maxRewardedCheckpoints.mul(_rewardDecreasePerCheckpoint) <= CHK_REWARD_PRECISION);
require(_checkpointRewardDelta <= CHK_REWARD_PRECISION);

rewardDecreasePerCheckpoint = _rewardDecreasePerCheckpoint;
maxRewardedCheckpoints = _maxRewardedCheckpoints;
checkpointRewardDelta = _checkpointRewardDelta;

_getOrCacheEventsHub().logRewardParams(_rewardDecreasePerCheckpoint, _maxRewardedCheckpoints, _checkpointRewardDelta);
}

function _getOrCacheEventsHub() private returns(EventsHub) {
EventsHub _eventsHub = EventsHub(eventsHub);
if (_eventsHub == EventsHub(0x0)) {
_eventsHub = EventsHub(Registry(registry).contractMap(keccak256("eventsHub")));
eventsHub = address(_eventsHub);
}
return _eventsHub;
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
pragma solidity 0.5.17;

contract StakeManagerStorageExtension {
address public eventsHub;
uint256 public rewardPerStake;
address public auctionImplementation;
address public extensionCode;
address[] public signers;

uint256 constant CHK_REWARD_PRECISION = 100;
uint256 public prevBlockInterval;
// how much less reward per skipped checkpoint, 0 - 100%
uint256 public rewardDecreasePerCheckpoint;
// how many skipped checkpoints to reward
uint256 public maxSkippedCheckpoints;
// how many checkpoints to reward
uint256 public maxRewardedCheckpoints;
// increase / decrease value for faster or slower checkpoints, 0 - 100%
uint256 public checkpointRewardDelta;
}
15 changes: 12 additions & 3 deletions contracts/staking/validatorShare/ValidatorShare.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ import {OwnableLockable} from "../../common/mixin/OwnableLockable.sol";
import {IStakeManager} from "../stakeManager/IStakeManager.sol";
import {IValidatorShare} from "./IValidatorShare.sol";
import {Initializable} from "../../common/mixin/Initializable.sol";
import {ValidatorShareStorageExtension} from "./ValidatorShareStorageExtension.sol";

contract ValidatorShare is IValidatorShare, ERC20NonTradable, OwnableLockable, Initializable, ValidatorShareStorageExtension {
contract ValidatorShare is IValidatorShare, ERC20NonTradable, OwnableLockable, Initializable {
struct DelegatorUnbond {
uint256 shares;
uint256 withdrawEpoch;
}

uint256 constant EXCHANGE_RATE_PRECISION = 100;
// maximum matic possible, even if rate will be 1 and all matic will be staken in one go, it will result in 10 ^ 58 shares
uint256 constant EXCHANGE_RATE_HIGH_PRECISION = 10**29;
Expand All @@ -26,9 +30,9 @@ contract ValidatorShare is IValidatorShare, ERC20NonTradable, OwnableLockable, I
uint256 public minAmount;

uint256 public totalStake_deprecated;
uint256 public rewardPerShare;
uint256 public activeAmount_deprecated;

uint256 public rewardPerShare;
bool public delegation;

uint256 public withdrawPool;
Expand All @@ -38,6 +42,11 @@ contract ValidatorShare is IValidatorShare, ERC20NonTradable, OwnableLockable, I
mapping(address => DelegatorUnbond) public unbonds;
mapping(address => uint256) public initalRewardPerShare;

mapping(address => uint256) public unbondNonces;
mapping(address => mapping(uint256 => DelegatorUnbond)) public unbonds_new;

EventsHub public eventsHub;

// onlyOwner will prevent this contract from initializing, since it's owner is going to be 0x0 address
function initialize(
uint256 _validatorId,
Expand Down

This file was deleted.

Loading

0 comments on commit b6e7800

Please sign in to comment.