Skip to content

Commit

Permalink
Merge branch 'sonic_sfc' into mike/old_redirects
Browse files Browse the repository at this point in the history
# Conflicts:
#	contracts/common/Initializable.sol
#	contracts/common/ReentrancyGuard.sol
#	contracts/ownership/Ownable.sol
#	contracts/sfc/NodeDriver.sol
#	contracts/sfc/NodeDriverAuth.sol
#	contracts/sfc/SFCBase.sol
#	contracts/sfc/Updater.sol
#	contracts/test/StubEvmWriter.sol
#	contracts/test/UnitTestSFC.sol
#	test/NodeDriver.ts
#	test/SFC.ts
  • Loading branch information
Mike-CZ committed Oct 24, 2024
2 parents 9bf3af6 + 846e556 commit b023328
Show file tree
Hide file tree
Showing 15 changed files with 210 additions and 79 deletions.
11 changes: 7 additions & 4 deletions contracts/common/Initializable.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import {IErrors} from "../IErrors.sol";

/**
* @title Initializable
*
Expand All @@ -15,7 +13,7 @@ import {IErrors} from "../IErrors.sol";
* a parent initializer twice, or ensure that all initializers are idempotent,
* because this is not dealt with automatically as with constructors.
*/
contract Initializable is IErrors {
contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
Expand All @@ -26,12 +24,17 @@ contract Initializable is IErrors {
*/
bool private initializing;

/**
* @dev The contract instance has already been initialized.
*/
error InvalidInitialization();

/**
* @dev Modifier to use in the initializer function of a contract.
*/
modifier initializer() {
if (!initializing && initialized) {
revert ContractInitialized();
revert InvalidInitialization();
}

bool isTopLevelCall = !initializing;
Expand Down
10 changes: 7 additions & 3 deletions contracts/common/ReentrancyGuard.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity ^0.8.9;

import {Initializable} from "./Initializable.sol";
import {IErrors} from "../IErrors.sol";

/**
* @dev Contract module that helps prevent reentrant calls to a function.
Expand All @@ -16,10 +15,15 @@ import {IErrors} from "../IErrors.sol";
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*/
contract ReentrancyGuard is IErrors, Initializable {
contract ReentrancyGuard is Initializable {
// counter to allow mutex lock with only one SSTORE operation
uint256 private _guardCounter;

/**
* @dev Reentrant call.
*/
error ReentrancyGuardReentrantCall();

function initialize() internal initializer {
// The counter starts at one to prevent changing it from zero to a non-zero
// value, which is a more expensive operation.
Expand All @@ -38,7 +42,7 @@ contract ReentrancyGuard is IErrors, Initializable {
uint256 localCounter = _guardCounter;
_;
if (localCounter != _guardCounter) {
revert ReentrantCall();
revert ReentrancyGuardReentrantCall();
}
}

Expand Down
14 changes: 14 additions & 0 deletions contracts/interfaces/IEVMWriter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

interface IEvmWriter {
function setBalance(address acc, uint256 value) external;

function copyCode(address acc, address from) external;

function swapCode(address acc, address where) external;

function setStorage(address acc, bytes32 key, bytes32 value) external;

function incNonce(address acc, uint256 diff) external;
}
17 changes: 13 additions & 4 deletions contracts/ownership/Ownable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
pragma solidity ^0.8.9;

import {Initializable} from "../common/Initializable.sol";
import {IErrors} from "../IErrors.sol";

/**
* @dev Contract module which provides a basic access control mechanism, where
Expand All @@ -13,9 +12,19 @@ import {IErrors} from "../IErrors.sol";
* `onlyOwner`, which can be aplied to your functions to restrict their use to
* the owner.
*/
contract Ownable is IErrors, Initializable {
contract Ownable is Initializable {
address private _owner;

/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);

/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);

event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

/**
Expand All @@ -38,7 +47,7 @@ contract Ownable is IErrors, Initializable {
*/
modifier onlyOwner() {
if (!isOwner()) {
revert NotOwner();
revert OwnableUnauthorizedAccount(msg.sender);
}
_;
}
Expand Down Expand Up @@ -75,7 +84,7 @@ contract Ownable is IErrors, Initializable {
*/
function _transferOwnership(address newOwner) internal {
if (newOwner == address(0)) {
revert ZeroAddress();
revert OwnableInvalidOwner(address(0));
}
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
Expand Down
23 changes: 7 additions & 16 deletions contracts/sfc/NodeDriver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,14 @@ pragma solidity ^0.8.9;

import {Initializable} from "../common/Initializable.sol";
import {NodeDriverAuth} from "./NodeDriverAuth.sol";
import {IErrors} from "../IErrors.sol";
import {IEvmWriter} from "../interfaces/IEVMWriter.sol";

interface EVMWriter {
function setBalance(address acc, uint256 value) external;

function copyCode(address acc, address from) external;

function swapCode(address acc, address where) external;

function setStorage(address acc, bytes32 key, bytes32 value) external;

function incNonce(address acc, uint256 diff) external;
}

contract NodeDriver is IErrors, Initializable {
contract NodeDriver is Initializable {
NodeDriverAuth internal backend;
EVMWriter internal evmWriter;
IEvmWriter internal evmWriter;

error NotNode();
error NotBackend();

event UpdatedBackend(address indexed backend);

Expand All @@ -45,7 +36,7 @@ contract NodeDriver is IErrors, Initializable {
function initialize(address _backend, address _evmWriterAddress) external initializer {
backend = NodeDriverAuth(_backend);
emit UpdatedBackend(_backend);
evmWriter = EVMWriter(_evmWriterAddress);
evmWriter = IEvmWriter(_evmWriterAddress);
}

function setBalance(address acc, uint256 value) external onlyBackend {
Expand Down
10 changes: 8 additions & 2 deletions contracts/sfc/NodeDriverAuth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@ import {Initializable} from "../common/Initializable.sol";
import {Ownable} from "../ownership/Ownable.sol";
import {SFCI} from "./SFCI.sol";
import {NodeDriver} from "./NodeDriver.sol";
import {IErrors} from "../IErrors.sol";

interface NodeDriverExecutable {
function execute() external;
}

contract NodeDriverAuth is IErrors, Initializable, Ownable {
contract NodeDriverAuth is Initializable, Ownable {
SFCI internal sfc;
NodeDriver internal driver;

error NotSFC();
error NotDriver();
error NotContract();
error SelfCodeHashMismatch();
error DriverCodeHashMismatch();
error RecipientNotSFC();

// 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.initialize(_owner);
Expand Down
5 changes: 5 additions & 0 deletions contracts/sfc/SFC.sol
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ contract SFC is SFCBase, Version {
return getEpochSnapshot[epoch].offlineBlocks[validatorID];
}

function getEpochEndBlock(uint256 epoch) public view returns (uint256) {
return getEpochSnapshot[epoch].endBlock;
}

function rewardsStash(address delegator, uint256 validatorID) public view returns (uint256) {
Rewards memory stash = _rewardsStash[delegator][validatorID];
return stash.lockupBaseReward + stash.lockupExtraReward + stash.unlockedReward;
Expand Down Expand Up @@ -389,6 +393,7 @@ contract SFC is SFCBase, Version {

currentSealedEpoch = currentEpoch();
snapshot.endTime = _now();
snapshot.endBlock = block.number;
snapshot.baseRewardPerSecond = c.baseRewardPerSecond();
snapshot.totalSupply = totalSupply;
}
Expand Down
74 changes: 72 additions & 2 deletions contracts/sfc/SFCBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,85 @@ pragma solidity ^0.8.9;

import {Decimal} from "../common/Decimal.sol";
import {SFCState} from "./SFCState.sol";
import {IErrors} from "../IErrors.sol";

contract SFCBase is IErrors, SFCState {
contract SFCBase is SFCState {
uint256 internal constant OK_STATUS = 0;
uint256 internal constant WITHDRAWN_BIT = 1;
uint256 internal constant OFFLINE_BIT = 1 << 3;
uint256 internal constant DOUBLESIGN_BIT = 1 << 7;
uint256 internal constant CHEATER_MASK = DOUBLESIGN_BIT;

// auth
error NotDriverAuth();
error NotAuthorized();

// addresses
error ZeroAddress();
error SameAddress();

// values
error ZeroAmount();
error ZeroRewards();

// pubkeys
error PubkeyExists();
error MalformedPubkey();
error SamePubkey();
error EmptyPubkey();
error PubkeyAllowedOnlyOnce();

// redirections
error SameRedirectionAuthorizer();
error Redirected();

// validators
error ValidatorNotExists();
error ValidatorExists();
error ValidatorNotActive();
error ValidatorDelegationLimitExceeded();
error WrongValidatorStatus();

// requests
error RequestedCompleted();
error RequestExists();
error RequestNotExists();

// transfers
error TransfersNotAllowed();
error TransferFailed();

// updater
error SFCAlreadyUpdated();
error SFCWrongVersion();
error SFCGovAlreadyUpdated();
error SFCWrongGovVersion();

// governance
error GovVotesRecountFailed();

// staking
error LockedStakeGreaterThanTotalStake();
error InsufficientSelfStake();
error NotEnoughUnlockedStake();
error NotEnoughLockedStake();
error NotEnoughTimePassed();
error NotEnoughEpochsPassed();
error StakeIsFullySlashed();
error IncorrectDuration();
error ValidatorLockupTooShort();
error TooManyReLocks();
error TooFrequentReLocks();
error LockupDurationDecreased();
error AlreadyLockedUp();
error NotLockedUp();

// stashing
error NothingToStash();

// slashing
error ValidatorNotSlashed();
error RefundRatioTooHigh();

event DeactivatedValidator(uint256 indexed validatorID, uint256 deactivatedEpoch, uint256 deactivatedTime);
event ChangedValidatorStatus(uint256 indexed validatorID, uint256 status);

Expand Down
3 changes: 3 additions & 0 deletions contracts/sfc/SFCI.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ interface SFCI {
view
returns (
uint256 endTime,
uint256 endBlock,
uint256 epochFee,
uint256 totalBaseRewardWeight,
uint256 totalTxRewardWeight,
Expand Down Expand Up @@ -137,6 +138,8 @@ interface SFCI {

function getEpochOfflineBlocks(uint256 epoch, uint256 validatorID) external view returns (uint256);

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

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

function getLockedStake(address delegator, uint256 toValidatorID) external view returns (uint256);
Expand Down
1 change: 1 addition & 0 deletions contracts/sfc/SFCState.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ contract SFCState is Initializable, Ownable {
mapping(uint256 => uint256) offlineBlocks;
uint256[] validatorIDs;
uint256 endTime;
uint256 endBlock;
uint256 epochFee;
uint256 totalBaseRewardWeight;
uint256 totalTxRewardWeight;
Expand Down
9 changes: 7 additions & 2 deletions contracts/sfc/Updater.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {ConstantsManager} from "./ConstantsManager.sol";
import {SFC} from "./SFC.sol";
import {SFCI} from "./SFCI.sol";
import {Version} from "../version/Version.sol";
import {IErrors} from "../IErrors.sol";

interface GovI {
function upgrade(address v) external;
Expand All @@ -22,7 +21,7 @@ interface GovVersion {
function version() external pure returns (bytes4);
}

contract Updater is IErrors {
contract Updater {
address public sfcFrom;
address public sfcLib;
address public sfcConsts;
Expand All @@ -31,6 +30,12 @@ contract Updater is IErrors {
address public voteBook;
address public owner;

error ZeroAddress();
error SFCAlreadyUpdated();
error SFCWrongVersion();
error SFCGovAlreadyUpdated();
error SFCWrongGovVersion();

constructor(
address _sfcFrom,
address _sfcLib,
Expand Down
4 changes: 2 additions & 2 deletions contracts/test/StubEvmWriter.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import {EVMWriter} from "../sfc/NodeDriver.sol";
import {IEvmWriter} from "../interfaces/IEVMWriter.sol";

contract StubEvmWriter is EVMWriter {
contract StubEvmWriter is IEvmWriter {
function setBalance(address acc, uint256 value) external {}

function copyCode(address acc, address from) external {}
Expand Down
Loading

0 comments on commit b023328

Please sign in to comment.