Skip to content

Commit

Permalink
Merge branch 'main' into mike/oz-n-04
Browse files Browse the repository at this point in the history
# Conflicts:
#	contracts/sfc/NodeDriverAuth.sol
  • Loading branch information
Mike-CZ committed Jan 31, 2025
2 parents 59ab0fb + 1d0a4e1 commit f2b0b39
Show file tree
Hide file tree
Showing 13 changed files with 318 additions and 104 deletions.
10 changes: 9 additions & 1 deletion contracts/interfaces/ISFC.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ interface ISFC {
);
event Delegated(address indexed delegator, uint256 indexed toValidatorID, uint256 amount);
event Undelegated(address indexed delegator, uint256 indexed toValidatorID, uint256 indexed wrID, uint256 amount);
event Withdrawn(address indexed delegator, uint256 indexed toValidatorID, uint256 indexed wrID, uint256 amount);
event Withdrawn(
address indexed delegator,
uint256 indexed toValidatorID,
uint256 indexed wrID,
uint256 amount,
uint256 penalty
);
event ClaimedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 rewards);
event RestakedRewards(address indexed delegator, uint256 indexed toValidatorID, uint256 rewards);
event BurntFTM(uint256 amount);
Expand Down Expand Up @@ -121,6 +127,8 @@ interface ISFC {

function getEpochEndBlock(uint256 epoch) external view returns (uint256);

function epochEndTime(uint256 epoch) external view returns (uint256);

function rewardsStash(address delegator, uint256 validatorID) external view returns (uint256);

function createValidator(bytes calldata pubkey) external payable;
Expand Down
11 changes: 11 additions & 0 deletions contracts/interfaces/IStakeSubscriber.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;

/**
* @title Stake Subscriber Interface
* @notice Used to recount votes from delegators in the governance contract
* @custom:security-contact [email protected]
*/
interface IStakeSubscriber {
function announceStakeChange(address delegator, address validator) external;
}
24 changes: 15 additions & 9 deletions contracts/sfc/ConstantsManager.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;

import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Decimal} from "../common/Decimal.sol";

/**
* @custom:security-contact [email protected]
*/
contract ConstantsManager is OwnableUpgradeable {
contract ConstantsManager is Ownable {
// Minimum amount of stake for a validator, i.e., 500000 FTM
uint256 public minSelfStake;
// Maximum ratio of delegations a validator can have, say, 15 times of self-stake
Expand Down Expand Up @@ -37,6 +37,10 @@ contract ConstantsManager is OwnableUpgradeable {
// Zero to disable validators deactivation by this metric.
uint64 public minAverageUptime;

// The address of the recipient that receives issued tokens
// as a counterparty to the burnt FTM tokens
address public issuedTokensRecipient;

/**
* @dev Given value is too small
*/
Expand All @@ -47,15 +51,13 @@ contract ConstantsManager is OwnableUpgradeable {
*/
error ValueTooLarge();

constructor(address owner) initializer {
__Ownable_init(owner);
}
constructor(address owner) Ownable(owner) {}

function updateMinSelfStake(uint256 v) external virtual onlyOwner {
if (v < 100000 * 1e18) {
if (v < 100000 * Decimal.unit()) {
revert ValueTooSmall();
}
if (v > 10000000 * 1e18) {
if (v > 10000000 * Decimal.unit()) {
revert ValueTooLarge();
}
minSelfStake = v;
Expand Down Expand Up @@ -113,10 +115,10 @@ contract ConstantsManager is OwnableUpgradeable {
}

function updateBaseRewardPerSecond(uint256 v) external virtual onlyOwner {
if (v < 0.5 * 1e18) {
if (v < Decimal.unit() / 2) {
revert ValueTooSmall();
}
if (v > 32 * 1e18) {
if (v > 32 * Decimal.unit()) {
revert ValueTooLarge();
}
baseRewardPerSecond = v;
Expand Down Expand Up @@ -179,4 +181,8 @@ contract ConstantsManager is OwnableUpgradeable {
}
minAverageUptime = v;
}

function updateIssuedTokensRecipient(address v) external virtual onlyOwner {
issuedTokensRecipient = v;
}
}
2 changes: 1 addition & 1 deletion contracts/sfc/NetworkInitializer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ contract NetworkInitializer {
NodeDriverAuth(_auth).initialize(_sfc, _driver, _owner);

ConstantsManager consts = new ConstantsManager(address(this));
consts.updateMinSelfStake(500000 * 1e18);
consts.updateMinSelfStake(500000 * Decimal.unit());
consts.updateMaxDelegatedRatio(16 * Decimal.unit());
consts.updateValidatorCommission((15 * Decimal.unit()) / 100);
consts.updateBurntFeeShare((20 * Decimal.unit()) / 100);
Expand Down
7 changes: 7 additions & 0 deletions contracts/sfc/NodeDriver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ contract NodeDriver is OwnableUpgradeable, UUPSUpgradeable, INodeDriver {
event UpdateNetworkVersion(uint256 version);
event AdvanceEpochs(uint256 num);

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}

/// Initialization is called only once, after the contract deployment.
/// Because the contract code is written directly into genesis, constructor cannot be used.
function initialize(address _backend, address _evmWriterAddress, address _owner) external initializer {
Expand Down Expand Up @@ -144,4 +149,6 @@ contract NodeDriver is OwnableUpgradeable, UUPSUpgradeable, INodeDriver {
function sealEpochValidators(uint256[] calldata nextValidatorIDs) external onlyNode {
backend.sealEpochValidators(nextValidatorIDs);
}

uint256[50] private __gap;
}
30 changes: 12 additions & 18 deletions contracts/sfc/NodeDriverAuth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ contract NodeDriverAuth is OwnableUpgradeable, UUPSUpgradeable {
error DriverCodeHashMismatch();
error RecipientNotSFC();

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}

// Initialize NodeDriverAuth, NodeDriver and SFC in one call to allow fewer genesis transactions
function initialize(address payable _sfc, address _driver, address _owner) external initializer {
__Ownable_init(_owner);
Expand Down Expand Up @@ -53,7 +58,6 @@ contract NodeDriverAuth is OwnableUpgradeable, UUPSUpgradeable {
_transferOwnership(executable);
INodeDriverExecutable(executable).execute();
_transferOwnership(newOwner);
//require(driver.backend() == address(this), "ownership of driver is lost");
if (_getCodeHash(address(this)) != selfCodeHash) {
revert SelfCodeHashMismatch();
}
Expand All @@ -63,7 +67,7 @@ contract NodeDriverAuth is OwnableUpgradeable, UUPSUpgradeable {
}

/// Execute a batch update of network configuration.
/// Run given contract with a permission of the NodeDriverAuth owner.
/// The executable will run with the privileges of the NodeDriverAuth owner.
/// Does not allow changing NodeDriver and NodeDriverAuth code.
function execute(address executable) external onlyOwner {
_execute(executable, owner(), _getCodeHash(address(this)), _getCodeHash(address(driver)));
Expand All @@ -83,13 +87,10 @@ contract NodeDriverAuth is OwnableUpgradeable, UUPSUpgradeable {

/// Mint native token. To be used by SFC for minting validators rewards.
function incBalance(address acc, uint256 diff) external onlySFC {
if (acc != address(sfc)) {
revert RecipientNotSFC();
}
driver.setBalance(acc, acc.balance + diff);
}

/// Upgrade code of given contract by coping it from other deployed contract.
/// Upgrade code of given contract by copying it from other deployed contract.
/// Avoids setting code to an external address.
function upgradeCode(address acc, address from) external onlyOwner {
if (!isContract(acc) || !isContract(from)) {
Expand All @@ -98,7 +99,7 @@ contract NodeDriverAuth is OwnableUpgradeable, UUPSUpgradeable {
driver.copyCode(acc, from);
}

/// Upgrade code of given contract by coping it from other deployed contract.
/// Upgrade code of given contract by copying it from other deployed contract.
/// Does not avoid setting code to an external address. (DANGEROUS!)
function copyCode(address acc, address from) external onlyOwner {
driver.copyCode(acc, from);
Expand Down Expand Up @@ -171,19 +172,12 @@ contract NodeDriverAuth is OwnableUpgradeable, UUPSUpgradeable {
}

function isContract(address account) internal view returns (bool) {
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly {
size := extcodesize(account)
}
return size > 0;
return account.code.length > 0;
}

function _getCodeHash(address addr) internal view returns (bytes32) {
bytes32 codeHash;
assembly {
codeHash := extcodehash(addr)
}
return codeHash;
return addr.codehash;
}

uint256[50] private __gap;
}
Loading

0 comments on commit f2b0b39

Please sign in to comment.