Solidity 0.7.x -> 0.8.x, integration StakingEscrow with Threshold Network, updated OpenZeppelin library

pull/2861/head
vzotova 2021-11-23 17:07:31 +03:00 committed by Kieran Prasch
parent 4dda3141ed
commit 5ced61f337
51 changed files with 1199 additions and 391 deletions

View File

@ -15,4 +15,4 @@ You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
SOLIDITY_COMPILER_VERSION = 'v0.7.6'
SOLIDITY_COMPILER_VERSION = 'v0.8.10'

View File

@ -19,7 +19,7 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
from typing import List, Dict
from nucypher.blockchain.eth.sol.compile.constants import (
CONTRACTS, ZEPPELIN, ARAGON
CONTRACTS, ZEPPELIN, ARAGON, THRESHOLD
)
from nucypher.blockchain.eth.sol.compile.types import CompilerConfiguration
@ -114,7 +114,7 @@ COMPILER_SETTINGS: Dict = dict(
outputSelection={"*": {"*": CONTRACT_OUTPUTS, "": FILE_OUTPUTS}}, # all contacts(*), all files("")
)
REMAPPINGS: List = [CONTRACTS, ZEPPELIN, ARAGON]
REMAPPINGS: List = [CONTRACTS, ZEPPELIN, ARAGON, THRESHOLD]
# Base configuration for programmatic usage
BASE_COMPILER_CONFIGURATION = CompilerConfiguration(

View File

@ -34,6 +34,7 @@ from nucypher.blockchain.eth import sol
SOLIDITY_SOURCE_ROOT: Path = Path(sol.__file__).parent / 'source'
ZEPPELIN = 'zeppelin'
ARAGON = 'aragon'
THRESHOLD = 'threshold'
# Do not compile contracts containing...
IGNORE_CONTRACT_PREFIXES: Tuple[str, ...] = (

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
// Minimum interface to interact with Aragon's Aggregator

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/lib/ReEncryptionValidator.sol";
import "contracts/lib/SignatureVerifier.sol";
@ -156,7 +156,7 @@ contract Adjudicator is Upgradeable {
// 4. Extract worker address from stamp signature.
address worker = SignatureVerifier.recover(
SignatureVerifier.hashEIP191(stamp, byte(0x45)), // Currently, we use version E (0x45) of EIP191 signatures
SignatureVerifier.hashEIP191(stamp, bytes1(0x45)), // Currently, we use version E (0x45) of EIP191 signatures
_workerIdentityEvidence);
address staker = escrow.stakerFromWorker(worker);
require(staker != address(0), "Worker must be related to a staker");

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/NuCypherToken.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "zeppelin/token/ERC20/ERC20.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "zeppelin/token/ERC20/SafeERC20.sol";
@ -270,7 +270,7 @@ contract PolicyManager is Upgradeable {
for (uint256 i = 0; i < _nodes.length; i++) {
address node = _nodes[i];
addFeeToNode(currentPeriod, endPeriod, node, feeRate, int256(feeRate));
addFeeToNode(currentPeriod, endPeriod, node, feeRate, int256(uint256(feeRate)));
policy.arrangements.push(ArrangementInfo(node, 0, 0));
}
}
@ -345,7 +345,7 @@ contract PolicyManager is Upgradeable {
!policy.disabled
);
policy.sponsor = msg.sender;
policy.sponsor = payable(msg.sender);
policy.startTimestamp = uint64(block.timestamp);
policy.endTimestamp = _endTimestamp;
policy.feeRate = _feeRate;
@ -476,7 +476,7 @@ contract PolicyManager is Upgradeable {
* @notice Withdraw fee by node
*/
function withdraw() external returns (uint256) {
return withdraw(msg.sender);
return withdraw(payable(msg.sender));
}
/**
@ -573,14 +573,14 @@ contract PolicyManager is Upgradeable {
// Check default value for feeDelta
uint16 lastRefundedPeriod = arrangement.lastRefundedPeriod;
if (nodeInfo.feeDelta[lastRefundedPeriod] == DEFAULT_FEE_DELTA) {
nodeInfo.feeDelta[lastRefundedPeriod] = -int256(policy.feeRate);
nodeInfo.feeDelta[lastRefundedPeriod] = -int256(uint256(policy.feeRate));
} else {
nodeInfo.feeDelta[lastRefundedPeriod] -= int256(policy.feeRate);
nodeInfo.feeDelta[lastRefundedPeriod] -= int256(uint256(policy.feeRate));
}
if (nodeInfo.feeDelta[endPeriod] == DEFAULT_FEE_DELTA) {
nodeInfo.feeDelta[endPeriod] = int256(policy.feeRate);
nodeInfo.feeDelta[endPeriod] = int256(uint256(policy.feeRate));
} else {
nodeInfo.feeDelta[endPeriod] += int256(policy.feeRate);
nodeInfo.feeDelta[endPeriod] += int256(uint256(policy.feeRate));
}
// Reset to default value if needed
@ -612,7 +612,7 @@ contract PolicyManager is Upgradeable {
if (numberOfActive == 0) {
policy.disabled = true;
// gas refund
policy.sponsor = address(0);
policy.sponsor = payable(address(0));
policy.owner = address(0);
policy.feeRate = 0;
policy.startTimestamp = 0;
@ -688,7 +688,7 @@ contract PolicyManager is Upgradeable {
* @return Revocation hash, EIP191 version 0x45 ('E')
*/
function getRevocationHash(bytes16 _policyId, address _node) public view returns (bytes32) {
return SignatureVerifier.hashEIP191(abi.encodePacked(_policyId, _node), byte(0x45));
return SignatureVerifier.hashEIP191(abi.encodePacked(_policyId, _node), bytes1(0x45));
}
/**
@ -832,7 +832,7 @@ contract PolicyManager is Upgradeable {
function delegateGetNodeInfo(address _target, address _node)
internal returns (MemoryNodeInfo memory result)
{
bytes32 memoryAddress = delegateGetData(_target, this.nodes.selector, 1, bytes32(uint256(_node)), 0);
bytes32 memoryAddress = delegateGetData(_target, this.nodes.selector, 1, bytes32(uint256(uint160(_node))), 0);
assembly {
result := memoryAddress
}
@ -899,7 +899,7 @@ contract PolicyManager is Upgradeable {
// Create fake Policy and NodeInfo to use them in verifyState(address)
Policy storage policy = policies[RESERVED_POLICY_ID];
policy.sponsor = msg.sender;
policy.sponsor = payable(msg.sender);
policy.owner = address(this);
policy.startTimestamp = 1;
policy.endTimestamp = 2;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "aragon/interfaces/IERC900History.sol";
@ -10,6 +10,7 @@ import "contracts/lib/Snapshot.sol";
import "contracts/proxy/Upgradeable.sol";
import "zeppelin/math/Math.sol";
import "zeppelin/token/ERC20/SafeERC20.sol";
import "threshold/IStaking.sol";
/**
@ -57,7 +58,7 @@ contract StakingEscrowStub is Upgradeable {
super.verifyState(_testTarget);
// we have to use real values even though this is a stub
require(address(delegateGet(_testTarget, this.token.selector)) == address(token));
require(address(uint160(delegateGet(_testTarget, this.token.selector))) == address(token));
}
}
@ -66,12 +67,11 @@ contract StakingEscrowStub is Upgradeable {
* @title StakingEscrow
* @notice Contract holds and locks stakers tokens.
* Each staker that locks their tokens will receive some compensation
* @dev |v6.1.1|
* @dev |v6.2.1|
*/
contract StakingEscrow is Upgradeable, IERC900History {
using Bits for uint256;
using SafeMath for uint256;
using Snapshot for uint128[];
using SafeERC20 for NuCypherToken;
@ -98,80 +98,100 @@ contract StakingEscrow is Upgradeable, IERC900History {
*/
event Slashed(address indexed staker, uint256 penalty, address indexed investigator, uint256 reward);
struct SubStakeInfo {
uint16 firstPeriod;
uint16 lastPeriod;
uint16 unlockingDuration;
uint128 lockedValue;
}
/**
* @notice Signals that vesting parameters were set for the staker
* @param staker Staker address
* @param releaseTimestamp Release timestamp
* @param releaseRate Release rate
*/
event VestingSet(address indexed staker, uint256 releaseTimestamp, uint256 releaseRate);
struct Downtime {
uint16 startPeriod;
uint16 endPeriod;
}
/**
* @notice Signals that the staker requested merge with T staking contract
* @param staker Staker address
* @param operator Operator address
*/
event MergeRequested(address indexed staker, address indexed operator);
/**
* @notice Signals that the staker confirmed merge with T staking contract
* @param staker Staker address
*/
event MergeConfirmed(address indexed staker);
struct StakerInfo {
uint256 value;
uint16 currentCommittedPeriod;
uint16 nextCommittedPeriod;
uint16 lastCommittedPeriod;
uint16 stub1; // former slot for lockReStakeUntilPeriod
uint256 completedWork;
uint16 workerStartPeriod; // period when worker was bonded
address worker;
uint16 stub1; // former slot for currentCommittedPeriod // TODO combine slots?
uint16 stub2; // former slot for nextCommittedPeriod
uint16 lastCommittedPeriod; // used only in depositFromWorkLock
uint16 stub4; // former slot for lockReStakeUntilPeriod
uint256 stub5; // former slot for completedWork
uint16 stub6; // former slot for workerStartPeriod
address stub7; // former slot for worker
uint256 flags; // uint256 to acquire whole slot and minimize operations on it
uint256 reservedSlot1;
uint256 reservedSlot2;
uint256 reservedSlot3;
uint256 vestingReleaseTimestamp;
uint256 vestingReleaseRate;
address operator;
uint256 reservedSlot4;
uint256 reservedSlot5;
Downtime[] pastDowntime;
SubStakeInfo[] subStakes;
uint128[] history;
uint256[] stub8; // former slot for pastDowntime
uint256[] stub9; // former slot for subStakes
uint128[] history; // TODO keep or remove?
}
// indices for flags (0-4 were in use, skip it in future)
// uint8 internal constant SNAPSHOTS_DISABLED_INDEX = 3;
uint8 internal constant MERGED_INDEX = 5;
uint256 internal constant ACCEPTABLE_STAKING_ERROR = 10**15;
NuCypherToken public immutable token;
WorkLockInterface public immutable workLock;
IStaking public immutable tStaking;
uint128 public previousPeriodSupply; // outdated
uint128 public currentPeriodSupply; // outdated
uint16 public currentMintingPeriod; // outdated
uint128 private stub1; // former slot for previousPeriodSupply
uint128 public currentPeriodSupply; // resulting token supply
uint16 private stub2; // former slot for currentMintingPeriod
mapping (address => StakerInfo) public stakerInfo;
address[] public stakers;
mapping (address => address) public stakerFromWorker; // outdated
mapping (address => address) private stub3; // former slot for stakerFromWorker
mapping (uint16 => uint256) stub1; // former slot for lockedPerPeriod
mapping (uint16 => uint256) private stub4; // former slot for lockedPerPeriod
uint128[] public balanceHistory; // outdated
address stub2; // former slot for PolicyManager
address stub3; // former slot for Adjudicator
address stub4; // former slot for WorkLock
address private stub5; // former slot for PolicyManager
address private stub6; // former slot for Adjudicator
address private stub7; // former slot for WorkLock
mapping (uint16 => uint256) public lockedPerPeriod; // outdated
mapping (uint16 => uint256) private stub8; // last former slot for lockedPerPeriod
/**
* @notice Constructor sets address of token contract and parameters for staking
* @param _token NuCypher token contract
* @param _workLock WorkLock contract. Zero address if there is no WorkLock
* @param _tStaking T token staking contract
*/
constructor(
NuCypherToken _token,
WorkLockInterface _workLock
WorkLockInterface _workLock,
IStaking _tStaking
) {
require(_token.totalSupply() > 0 &&
_tStaking.stakedNu(address(0)) == 0 &&
(address(_workLock) == address(0) || _workLock.token() == _token),
"Input addresses must be deployed contracts"
);
token = _token;
workLock = _workLock;
tStaking = _tStaking;
}
/**
@ -183,6 +203,15 @@ contract StakingEscrow is Upgradeable, IERC900History {
_;
}
/**
* @dev Checks caller is T staking contract
*/
modifier onlyTStakingContract()
{
require(msg.sender == address(tStaking), "Caller must be the T staking contract");
_;
}
/**
* @dev Checks caller is WorkLock contract
*/
@ -200,17 +229,17 @@ contract StakingEscrow is Upgradeable, IERC900History {
return stakerInfo[_staker].value;
}
// /**
// * @notice Get all flags for the staker
// */
// function getFlags(address _staker)
// external view returns (
// bool snapshots
// )
// {
// StakerInfo storage info = stakerInfo[_staker];
// snapshots = !info.flags.bitSet(SNAPSHOTS_DISABLED_INDEX);
// }
/**
* @notice Get all flags for the staker
*/
function getFlags(address _staker)
external view returns (
bool merged
)
{
StakerInfo storage info = stakerInfo[_staker];
merged = info.flags.bitSet(MERGED_INDEX);
}
/**
* @notice Get work that completed by the staker
@ -258,6 +287,105 @@ contract StakingEscrow is Upgradeable, IERC900History {
emit Deposited(_staker, _value);
}
/**
* @notice Withdraw available amount of NU tokens to staker
* @param _value Amount of tokens to withdraw
*/
function withdraw(uint256 _value) external onlyStaker {
StakerInfo storage info = stakerInfo[msg.sender];
require(info.flags.bitSet(MERGED_INDEX), "Merge must be confirmed");
require(
_value + tStaking.stakedNu(info.operator) <= info.value,
"Not enough tokens unstaked in T staking contract"
);
require(
_value + getVestedTokens(msg.sender) <= info.value,
"Not enough tokens released during vesting"
);
info.value -= _value;
addSnapshot(info, - int256(_value));
token.safeTransfer(msg.sender, _value);
emit Withdrawn(msg.sender, _value);
}
/**
* @notice Returns amount of not released yet tokens for staker
*/
function getVestedTokens(address _staker) public view returns (uint256) {
StakerInfo storage info = stakerInfo[_staker];
if (info.vestingReleaseTimestamp <= block.timestamp) {
return 0;
}
return (block.timestamp - info.vestingReleaseTimestamp) * info.vestingReleaseRate;
}
/**
* @notice Setup vesting parameters
* @param _stakers Array of stakers
* @param _releaseTimestamp Array of timestamps when stake will be released
* @param _releaseRate Array of release rates
*/
function setupVesting(
address[] calldata _stakers,
uint256[] calldata _releaseTimestamp,
uint256[] calldata _releaseRate
) external onlyOwner {
require(_stakers.length == _releaseTimestamp.length &&
_releaseTimestamp.length == _releaseRate.length,
"Input arrays must have same number of elements"
);
for (uint256 i = 0; i < _stakers.length; i++) {
address staker = _stakers[i];
StakerInfo storage info = stakerInfo[staker];
require(info.vestingReleaseTimestamp == 0, "Vesting parameters can be set only once");
info.vestingReleaseTimestamp = _releaseTimestamp[i];
info.vestingReleaseRate = _releaseRate[i];
require(getVestedTokens(staker) > 0, "Vesting parameters must be set properly");
emit VestingSet(staker, info.vestingReleaseTimestamp, info.vestingReleaseRate);
}
}
/**
* @notice Request migration to threshold network
* @param _staker Staker address
* @param _operator Operator address
* @return Amount of tokens
*/
function requestMerge(address _staker, address _operator)
external onlyTStakingContract returns (uint256)
{
StakerInfo storage info = stakerInfo[_staker];
require(
info.operator == address(0) || info.operator == _operator,
"Operator already set for the staker"
);
if (info.operator == address(0)) {
info.operator = _operator;
emit MergeRequested(_staker, _operator);
}
return info.value;
}
/**
* @notice Confirm migration to threshold network
* @param _staker Staker address
*/
function confirmMerge(address _staker) external {
StakerInfo storage info = stakerInfo[_staker];
require(info.operator != address(0), "Staker didn't request merge");
require(!info.flags.bitSet(MERGED_INDEX), "Merge already confirmed");
uint256 stakedNu = tStaking.stakedNu(info.operator);
require(stakedNu + ACCEPTABLE_STAKING_ERROR >= info.value, "All tokens must be staked");
uint96 minStakedNuInT = tStaking.getMinStaked(info.operator, IStaking.StakeType.NU);
(,, uint96 stakedNuInT) = tStaking.stakes(info.operator);
require(minStakedNuInT == stakedNuInT, "All tokens must be authorized");
info.flags = info.flags.toggleBit(MERGED_INDEX);
emit MergeConfirmed(_staker);
}
//-------------------------Slashing-------------------------
/**
* @notice Slash the staker's stake and reward the investigator
@ -272,7 +400,7 @@ contract StakingEscrow is Upgradeable, IERC900History {
address _investigator,
uint256 _reward
)
internal
external onlyTStakingContract
{
require(_penalty > 0, "Penalty must be specified");
StakerInfo storage info = stakerInfo[_staker];
@ -298,54 +426,6 @@ contract StakingEscrow is Upgradeable, IERC900History {
return stakers.length;
}
/**
* @notice Return the length of the array of sub stakes
*/
function getSubStakesLength(address _staker) external view returns (uint256) {
return stakerInfo[_staker].subStakes.length;
}
/**
* @notice Return the information about sub stake
*/
function getSubStakeInfo(address _staker, uint256 _index)
// TODO change to structure when ABIEncoderV2 is released (#1501)
// public view returns (SubStakeInfo)
// TODO "virtual" only for tests, probably will be removed after #1512
external view virtual returns (
uint16 firstPeriod,
uint16 lastPeriod,
uint16 unlockingDuration,
uint128 lockedValue
)
{
SubStakeInfo storage info = stakerInfo[_staker].subStakes[_index];
firstPeriod = info.firstPeriod;
lastPeriod = info.lastPeriod;
unlockingDuration = info.unlockingDuration;
lockedValue = info.lockedValue;
}
/**
* @notice Return the length of the array of past downtime
*/
function getPastDowntimeLength(address _staker) external view returns (uint256) {
return stakerInfo[_staker].pastDowntime.length;
}
/**
* @notice Return the information about past downtime
*/
function getPastDowntime(address _staker, uint256 _index)
// TODO change to structure when ABIEncoderV2 is released (#1501)
// public view returns (Downtime)
external view returns (uint16 startPeriod, uint16 endPeriod)
{
Downtime storage downtime = stakerInfo[_staker].pastDowntime[_index];
startPeriod = downtime.startPeriod;
endPeriod = downtime.endPeriod;
}
//------------------ ERC900 connectors ----------------------
function totalStakedForAt(address _owner, uint256 _blockNumber) public view override returns (uint256) {
@ -390,10 +470,12 @@ contract StakingEscrow is Upgradeable, IERC900History {
address stakerAddress = stakers[0];
require(address(uint160(delegateGet(_testTarget, this.stakers.selector, 0))) == stakerAddress);
StakerInfo storage info = stakerInfo[stakerAddress];
bytes32 staker = bytes32(uint256(stakerAddress));
bytes32 staker = bytes32(uint256(uint160(stakerAddress)));
StakerInfo memory infoToCheck = delegateGetStakerInfo(_testTarget, staker);
require(
infoToCheck.value == info.value &&
require(infoToCheck.value == info.value &&
infoToCheck.vestingReleaseTimestamp == info.vestingReleaseTimestamp &&
infoToCheck.vestingReleaseRate == info.vestingReleaseRate &&
infoToCheck.operator == info.operator &&
infoToCheck.flags == info.flags
);
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0; // TODO use 0.7.x version and revert changes ?
import "zeppelin/math/SafeMath.sol";
@ -335,7 +335,7 @@ contract WorkLock is Ownable {
if (refundETH > minAllowedBid) {
bonusETHSupply = bonusETHSupply.sub(refundETH - minAllowedBid);
}
msg.sender.sendValue(refundETH);
payable(msg.sender).sendValue(refundETH);
emit Canceled(msg.sender, refundETH);
}
@ -444,7 +444,7 @@ contract WorkLock is Ownable {
uint256 refund = compensation[msg.sender];
require(refund > 0, "There is no compensation");
compensation[msg.sender] = 0;
msg.sender.sendValue(refund);
payable(msg.sender).sendValue(refund);
emit CompensationWithdrawn(msg.sender, refund);
}
@ -550,6 +550,6 @@ contract WorkLock is Ownable {
info.completedWork = info.completedWork.add(completedWork);
emit Refund(msg.sender, refundETH, completedWork);
msg.sender.sendValue(refundETH);
payable(msg.sender).sendValue(refundETH);
}
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
interface IForwarder {

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
interface TokenManager {

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/dao/IForwarder.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "zeppelin/math/SafeMath.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
/**
* @dev Taken from https://github.com/ethereum/solidity-examples/blob/master/src/bits/Bits.sol

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/lib/UmbralDeserializer.sol";
import "contracts/lib/SignatureVerifier.sol";
@ -385,7 +385,7 @@ library ReEncryptionValidator {
) internal pure returns(bool) {
uint256 curve_order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
address signer = ecrecover(0, uint8(27 + (y1 % 2)), bytes32(x1), bytes32(mulmod(scalar, x1, curve_order)));
address xyAddress = address(uint256(keccak256(abi.encodePacked(qx, qy))) & 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
address xyAddress = address(uint160(uint256(keccak256(abi.encodePacked(qx, qy))) & 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF));
return xyAddress == signer;
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
/**
@ -101,16 +101,16 @@ library SignatureVerifier {
*/
function hashEIP191(
bytes memory _message,
byte _version
bytes1 _version
)
internal
view
returns (bytes32 result)
{
if(_version == byte(0x00)){ // Version 0: Data with intended validator
if(_version == bytes1(0x00)){ // Version 0: Data with intended validator
address validator = address(this);
return keccak256(abi.encodePacked(byte(0x19), byte(0x00), validator, _message));
} else if (_version == byte(0x45)){ // Version E: personal_sign messages
return keccak256(abi.encodePacked(bytes1(0x19), bytes1(0x00), validator, _message));
} else if (_version == bytes1(0x45)){ // Version E: personal_sign messages
uint256 length = _message.length;
require(length > 0, "Empty message not allowed for version E");
@ -124,11 +124,11 @@ library SignatureVerifier {
length = _message.length;
uint256 index = digits - 1;
while (length != 0) {
lengthAsText[index--] = byte(uint8(48 + length % 10));
lengthAsText[index--] = bytes1(uint8(48 + length % 10));
length /= 10;
}
return keccak256(abi.encodePacked(byte(0x19), EIP191_VERSION_E_HEADER, lengthAsText, _message));
return keccak256(abi.encodePacked(bytes1(0x19), EIP191_VERSION_E_HEADER, lengthAsText, _message));
} else {
revert("Unsupported EIP191 version");
}
@ -147,7 +147,7 @@ library SignatureVerifier {
bytes memory _message,
bytes memory _signature,
bytes memory _publicKey,
byte _version
bytes1 _version
)
internal
view

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
/**

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
/**
@ -259,7 +259,7 @@ library UmbralDeserializer {
/**
* @notice Read 1 byte from memory in the pointer position
*/
function getByte(uint256 _pointer) internal pure returns (byte result) {
function getByte(uint256 _pointer) internal pure returns (bytes1 result) {
bytes32 word;
assembly {
word := mload(_pointer)

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "./Upgradeable.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "zeppelin/ownership/Ownable.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "zeppelin/ownership/Ownable.sol";
import "zeppelin/utils/Address.sol";

View File

@ -1,16 +1,14 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "zeppelin/ownership/Ownable.sol";
import "zeppelin/math/SafeMath.sol";
import "contracts/staking_contracts/AbstractStakingContract.sol";
/**
* @notice Contract acts as delegate for sub-stakers
**/
contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
using SafeMath for uint256;
using Address for address payable;
using SafeERC20 for NuCypherToken;
@ -115,9 +113,9 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
function depositTokens(uint256 _value) external {
require(isDepositAllowed(), "Deposit must be enabled");
require(_value > 0, "Value must be not empty");
totalDepositedTokens = totalDepositedTokens.add(_value);
totalDepositedTokens += _value;
Delegator storage delegator = delegators[msg.sender];
delegator.depositedTokens = delegator.depositedTokens.add(_value);
delegator.depositedTokens += _value;
token.safeTransferFrom(msg.sender, address(this), _value);
emit TokensDeposited(msg.sender, _value, delegator.depositedTokens);
}
@ -131,7 +129,7 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
// tokens which directly belong to pool
uint256 freeTokens = token.balanceOf(address(this));
// tokens in excess of the initially deposited
uint256 reward = stakedTokens.add(freeTokens).sub(totalDepositedTokens);
uint256 reward = stakedTokens + freeTokens - totalDepositedTokens;
// check how many of reward tokens belong directly to pool
if (reward > freeTokens) {
return freeTokens;
@ -144,7 +142,7 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
* Available and withdrawn reward together to use in delegator/owner reward calculations
*/
function getCumulativeReward() public view returns (uint256) {
return getAvailableReward().add(totalWithdrawnReward);
return getAvailableReward() + totalWithdrawnReward;
}
/**
@ -159,7 +157,7 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
// usual case
if (totalDepositedTokens != 0) {
uint256 fraction = getWorkerFraction();
maxAllowableReward = reward.mul(fraction).div(BASIS_FRACTION);
maxAllowableReward = reward * fraction / BASIS_FRACTION;
// special case when there are no delegators
} else {
maxAllowableReward = reward;
@ -188,9 +186,8 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
// calculate total reward for delegator including historical reward
// excluding worker share
uint256 maxAllowableReward = reward.mul(delegator.depositedTokens).mul(BASIS_FRACTION - fraction).div(
totalDepositedTokens.mul(BASIS_FRACTION)
);
uint256 maxAllowableReward = reward * delegator.depositedTokens * (BASIS_FRACTION - fraction)
/ (totalDepositedTokens * BASIS_FRACTION);
// check that worker has any new reward
if (maxAllowableReward > delegator.withdrawnReward) {
@ -214,8 +211,8 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
availableReward > 0,
"There is no available reward to withdraw"
);
workerWithdrawnReward = workerWithdrawnReward.add(availableReward);
totalWithdrawnReward = totalWithdrawnReward.add(availableReward);
workerWithdrawnReward += availableReward;
totalWithdrawnReward += availableReward;
token.safeTransfer(msg.sender, availableReward);
emit TokensWithdrawn(msg.sender, availableReward, 0);
@ -233,8 +230,8 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
uint256 availableReward = getAvailableDelegatorReward(msg.sender);
require( _value <= availableReward, "Requested amount of tokens exceeded allowed portion");
delegator.withdrawnReward = delegator.withdrawnReward.add(_value);
totalWithdrawnReward = totalWithdrawnReward.add(_value);
delegator.withdrawnReward += _value;
totalWithdrawnReward += _value;
token.safeTransfer(msg.sender, _value);
emit TokensWithdrawn(msg.sender, _value, delegator.depositedTokens);
@ -249,7 +246,7 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
Delegator storage delegator = delegators[msg.sender];
uint256 availableReward = getAvailableDelegatorReward(msg.sender);
uint256 value = availableReward.add(delegator.depositedTokens);
uint256 value = availableReward + delegator.depositedTokens;
require(value <= balance, "Not enough tokens in the contract");
// TODO remove double reading: availableReward and availableWorkerReward use same calls to external contracts
@ -259,18 +256,18 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
uint256 availableETH = getAvailableDelegatorETH(msg.sender);
// prevent losing reward for worker after calculations
uint256 workerReward = availableWorkerReward.mul(delegator.depositedTokens).div(totalDepositedTokens);
uint256 workerReward = availableWorkerReward * delegator.depositedTokens / totalDepositedTokens;
if (workerReward > 0) {
require(value.add(workerReward) <= balance, "Not enough tokens in the contract");
require(value + workerReward <= balance, "Not enough tokens in the contract");
token.safeTransfer(workerOwner, workerReward);
emit TokensWithdrawn(workerOwner, workerReward, 0);
}
uint256 withdrawnToDecrease = workerWithdrawnReward.mul(delegator.depositedTokens).div(totalDepositedTokens);
uint256 withdrawnToDecrease = workerWithdrawnReward * delegator.depositedTokens / totalDepositedTokens;
workerWithdrawnReward = workerWithdrawnReward.sub(withdrawnToDecrease);
totalWithdrawnReward = totalWithdrawnReward.sub(withdrawnToDecrease).sub(delegator.withdrawnReward);
totalDepositedTokens = totalDepositedTokens.sub(delegator.depositedTokens);
workerWithdrawnReward -= withdrawnToDecrease;
totalWithdrawnReward -= withdrawnToDecrease + delegator.withdrawnReward;
totalDepositedTokens -= delegator.depositedTokens;
delegator.withdrawnReward = 0;
delegator.depositedTokens = 0;
@ -278,11 +275,11 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
token.safeTransfer(msg.sender, value);
emit TokensWithdrawn(msg.sender, value, 0);
totalWithdrawnETH = totalWithdrawnETH.sub(delegator.withdrawnETH);
totalWithdrawnETH -= delegator.withdrawnETH;
delegator.withdrawnETH = 0;
if (availableETH > 0) {
emit ETHWithdrawn(msg.sender, availableETH);
msg.sender.sendValue(availableETH);
payable(msg.sender).sendValue(availableETH);
}
}
@ -293,10 +290,10 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
Delegator storage delegator = delegators[_delegator];
uint256 balance = address(this).balance;
// ETH balance + already withdrawn
balance = balance.add(totalWithdrawnETH);
uint256 maxAllowableETH = balance.mul(delegator.depositedTokens).div(totalDepositedTokens);
balance += totalWithdrawnETH;
uint256 maxAllowableETH = balance * delegator.depositedTokens / totalDepositedTokens;
uint256 availableETH = maxAllowableETH.sub(delegator.withdrawnETH);
uint256 availableETH = maxAllowableETH - delegator.withdrawnETH;
if (availableETH > balance) {
availableETH = balance;
}
@ -310,11 +307,11 @@ contract PoolingStakingContractV2 is InitializableStakingContract, Ownable {
Delegator storage delegator = delegators[msg.sender];
uint256 availableETH = getAvailableDelegatorETH(msg.sender);
require(availableETH > 0, "There is no available ETH to withdraw");
delegator.withdrawnETH = delegator.withdrawnETH.add(availableETH);
delegator.withdrawnETH += availableETH;
totalWithdrawnETH = totalWithdrawnETH.add(availableETH);
totalWithdrawnETH += availableETH;
emit ETHWithdrawn(msg.sender, availableETH);
msg.sender.sendValue(availableETH);
payable(msg.sender).sendValue(availableETH);
}
/**

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/staking_contracts/AbstractStakingContract.sol";

View File

@ -0,0 +1,358 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.0;
/// @title Interface of Threshold Network staking contract
/// @notice The staking contract enables T owners to have their wallets offline
/// and their stake operated by operators on their behalf. All off-chain
/// client software should be able to run without exposing operators
/// private key and should not require any owners keys at all.
/// The stake delegation optimizes the network throughput without
/// compromising the security of the owners stake.
interface IStaking {
enum StakeType {
NU,
KEEP,
T
}
//
//
// Delegating a stake
//
//
/// @notice Creates a delegation with `msg.sender` owner with the given
/// operator, beneficiary, and authorizer. Transfers the given
/// amount of T to the staking contract.
/// @dev The owner of the delegation needs to have the amount approved to
/// transfer to the staking contract.
function stake(
address operator,
address payable beneficiary,
address authorizer,
uint96 amount
) external;
/// @notice Copies delegation from the legacy KEEP staking contract to T
/// staking contract. No tokens are transferred. Caches the active
/// stake amount from KEEP staking contract. Can be called by
/// anyone.
function stakeKeep(address operator) external;
/// @notice Copies delegation from the legacy NU staking contract to T
/// staking contract, additionally appointing beneficiary and
/// authorizer roles. Caches the amount staked in NU staking
/// contract. Can be called only by the original delegation owner.
function stakeNu(
address operator,
address payable beneficiary,
address authorizer
) external;
/// @notice Refresh Keep stake owner. Can be called only by the old owner.
function refreshKeepStakeOwner(address operator) external;
/// @notice Allows the Governance to set the minimum required stake amount.
/// This amount is required to protect against griefing the staking
/// contract and individual applications are allowed to require
/// higher minimum stakes if necessary.
function setMinimumStakeAmount(uint96 amount) external;
//
//
// Authorizing an application
//
//
/// @notice Allows the Governance to approve the particular application
/// before individual stake authorizers are able to authorize it.
function approveApplication(address application) external;
/// @notice Increases the authorization of the given operator for the given
/// application by the given amount. Can only be called by the given
/// operators authorizer.
/// @dev Calls `authorizationIncreased(address operator, uint256 amount)`
/// on the given application to notify the application about
/// authorization change. See `IApplication`.
function increaseAuthorization(
address operator,
address application,
uint96 amount
) external;
/// @notice Requests decrease of the authorization for the given operator on
/// the given application by the provided amount.
/// It may not change the authorized amount immediatelly. When
/// it happens depends on the application. Can only be called by the
/// given operators authorizer. Overwrites pending authorization
/// decrease for the given operator and application.
/// @dev Calls `authorizationDecreaseRequested(address operator, uint256 amount)`
/// on the given application. See `IApplication`.
function requestAuthorizationDecrease(
address operator,
address application,
uint96 amount
) external;
/// @notice Requests decrease of all authorizations for the given operator on
/// the applications by all authorized amount.
/// It may not change the authorized amount immediatelly. When
/// it happens depends on the application. Can only be called by the
/// given operators authorizer. Overwrites pending authorization
/// decrease for the given operator and application.
/// @dev Calls `authorizationDecreaseRequested(address operator, uint256 amount)`
/// for each authorized application. See `IApplication`.
function requestAuthorizationDecrease(address operator) external;
/// @notice Called by the application at its discretion to approve the
/// previously requested authorization decrease request. Can only be
/// called by the application that was previously requested to
/// decrease the authorization for that operator.
/// Returns resulting authorized amount for the application.
function approveAuthorizationDecrease(address operator)
external
returns (uint96);
/// @notice Decreases the authorization for the given `operator` on
/// the given disabled `application`, for all authorized amount.
/// Can be called by anyone.
function forceDecreaseAuthorization(address operator, address application)
external;
/// @notice Pauses the given applications eligibility to slash stakes.
/// Besides that stakers can't change authorization to the application.
/// Can be called only by the Panic Button of the particular
/// application. The paused application can not slash stakes until
/// it is approved again by the Governance using `approveApplication`
/// function. Should be used only in case of an emergency.
function pauseApplication(address application) external;
/// @notice Disables the given application. The disabled application can't
/// slash stakers. Also stakers can't increase authorization to that
/// application but can decrease without waiting by calling
/// `requestAuthorizationDecrease` at any moment. Can be called only
/// by the governance. The disabled application can't be approved
/// again. Should be used only in case of an emergency.
function disableApplication(address application) external;
/// @notice Sets the Panic Button role for the given application to the
/// provided address. Can only be called by the Governance. If the
/// Panic Button for the given application should be disabled, the
/// role address should be set to 0x0 address.
function setPanicButton(address application, address panicButton) external;
/// @notice Sets the maximum number of applications one operator can
/// authorize. Used to protect against DoSing slashing queue.
/// Can only be called by the Governance.
function setAuthorizationCeiling(uint256 ceiling) external;
//
//
// Stake top-up
//
//
/// @notice Increases the amount of the stake for the given operator.
/// Can be called only by the owner or operator.
/// @dev The sender of this transaction needs to have the amount approved to
/// transfer to the staking contract.
function topUp(address operator, uint96 amount) external;
/// @notice Propagates information about stake top-up from the legacy KEEP
/// staking contract to T staking contract. Can be called only by
/// the owner or operator.
function topUpKeep(address operator) external;
/// @notice Propagates information about stake top-up from the legacy NU
/// staking contract to T staking contract. Can be called only by
/// the owner or operator.
function topUpNu(address operator) external;
//
//
// Undelegating a stake (unstaking)
//
//
/// @notice Reduces the liquid T stake amount by the provided amount and
/// withdraws T to the owner. Reverts if there is at least one
/// authorization higher than the sum of the legacy stake and
/// remaining liquid T stake or if the unstake amount is higher than
/// the liquid T stake amount. Can be called only by the owner or
/// operator.
function unstakeT(address operator, uint96 amount) external;
/// @notice Sets the legacy KEEP staking contract active stake amount cached
/// in T staking contract to 0. Reverts if the amount of liquid T
/// staked in T staking contract is lower than the highest
/// application authorization. This function allows to unstake from
/// KEEP staking contract and still being able to operate in T
/// network and earning rewards based on the liquid T staked. Can be
/// called only by the delegation owner and operator.
function unstakeKeep(address operator) external;
/// @notice Reduces cached legacy NU stake amount by the provided amount.
/// Reverts if there is at least one authorization higher than the
/// sum of remaining legacy NU stake and liquid T stake for that
/// operator or if the untaked amount is higher than the cached
/// legacy stake amount. If succeeded, the legacy NU stake can be
/// partially or fully undelegated on the legacy staking contract.
/// This function allows to unstake from NU staking contract and
/// still being able to operate in T network and earning rewards
/// based on the liquid T staked. Can be called only by the
/// delegation owner and operator.
function unstakeNu(address operator, uint96 amount) external;
/// @notice Sets cached legacy stake amount to 0, sets the liquid T stake
/// amount to 0 and withdraws all liquid T from the stake to the
/// owner. Reverts if there is at least one non-zero authorization.
/// Can be called only by the delegation owner and operator.
function unstakeAll(address operator) external;
//
//
// Keeping information in sync
//
//
/// @notice Notifies about the discrepancy between legacy KEEP active stake
/// and the amount cached in T staking contract. Slashes the operator
/// in case the amount cached is higher than the actual active stake
/// amount in KEEP staking contract. Needs to update authorizations
/// of all affected applications and execute an involuntary
/// allocation decrease on all affected applications. Can be called
/// by anyone, notifier receives a reward.
function notifyKeepStakeDiscrepancy(address operator) external;
/// @notice Notifies about the discrepancy between legacy NU active stake
/// and the amount cached in T staking contract. Slashes the
/// operator in case the amount cached is higher than the actual
/// active stake amount in NU staking contract. Needs to update
/// authorizations of all affected applications and execute an
/// involuntary allocation decrease on all affected applications.
/// Can be called by anyone, notifier receives a reward.
function notifyNuStakeDiscrepancy(address operator) external;
/// @notice Sets the penalty amount for stake discrepancy and reward
/// multiplier for reporting it. The penalty is seized from the
/// operator account, and 5% of the penalty, scaled by the
/// multiplier, is given to the notifier. The rest of the tokens are
/// burned. Can only be called by the Governance. See `seize` function.
function setStakeDiscrepancyPenalty(
uint96 penalty,
uint256 rewardMultiplier
) external;
/// @notice Sets reward in T tokens for notification of misbehaviour
/// of one operator. Can only be called by the governance.
function setNotificationReward(uint96 reward) external;
/// @notice Transfer some amount of T tokens as reward for notifications
/// of misbehaviour
function pushNotificationReward(uint96 reward) external;
/// @notice Withdraw some amount of T tokens from notifiers treasury.
/// Can only be called by the governance.
function withdrawNotificationReward(address recipient, uint96 amount)
external;
/// @notice Adds operators to the slashing queue along with the amount that
/// should be slashed from each one of them. Can only be called by
/// application authorized for all operators in the array.
function slash(uint96 amount, address[] memory operators) external;
/// @notice Adds operators to the slashing queue along with the amount.
/// The notifier will receive reward per each operator from
/// notifiers treasury. Can only be called by application
/// authorized for all operators in the array.
function seize(
uint96 amount,
uint256 rewardMultipier,
address notifier,
address[] memory operators
) external;
/// @notice Takes the given number of queued slashing operations and
/// processes them. Receives 5% of the slashed amount.
/// Executes `involuntaryAllocationDecrease` function on each
/// affected application.
function processSlashing(uint256 count) external;
//
//
// Auxiliary functions
//
//
/// @notice Returns the authorized stake amount of the operator for the
/// application.
function authorizedStake(address operator, address application)
external
view
returns (uint96);
/// @notice Returns staked amount of T, Keep and Nu for the specified
/// operator.
/// @dev All values are in T denomination
function stakes(address operator)
external
view
returns (
uint96 tStake,
uint96 keepInTStake,
uint96 nuInTStake
);
/// @notice Returns start staking timestamp for T stake.
/// @dev This value is set at most once, and only when a stake is created
/// with T tokens. If a stake is created from a legacy stake,
/// this value will remain as zero
function getStartTStakingTimestamp(address operator)
external
view
returns (uint256);
/// @notice Returns staked amount of NU for the specified operator
function stakedNu(address operator) external view returns (uint256);
/// @notice Gets the stake owner, the beneficiary and the authorizer
/// for the specified operator address.
/// @return owner Stake owner address.
/// @return beneficiary Beneficiary address.
/// @return authorizer Authorizer address.
function rolesOf(address operator)
external
view
returns (
address owner,
address payable beneficiary,
address authorizer
);
/// @notice Returns length of application array
function getApplicationsLength() external view returns (uint256);
/// @notice Returns length of slashing queue
function getSlashingQueueLength() external view returns (uint256);
/// @notice Returns minimum possible stake for T, KEEP or NU in T denomination
/// @dev For example, if the given operator has 10 T, 20 KEEP, and
/// 30 NU staked, their max authorization is 40, then `getMinStaked`
/// for that operator returns 0 for KEEP stake type, 10 for NU stake
/// type, and 0 for T stake type. In other words, minimum staked
/// amount for the given stake type is the minimum amount of stake
/// of the given type that needs to be preserved in the contract to
/// satisfy the maximum application authorization given the amounts
/// of other stake types for that operator.
function getMinStaked(address operator, StakeType stakeTypes)
external
view
returns (uint96);
/// @notice Returns available amount to authorize for the specified application
function getAvailableToAuthorize(address operator, address application)
external
view
returns (uint96);
}

View File

@ -1,11 +1,10 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.3.2 (utils/math/Math.sol)
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
/**
* @title Math
* @dev Assorted math operations
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
/**
@ -23,12 +22,22 @@ library Math {
}
/**
* @dev Calculates the average of two numbers. Since these are integers,
* averages of an even and odd number cannot be represented, and will be
* rounded down.
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow, so we distribute
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a / b + (a % b == 0 ? 0 : 1);
}
}

View File

@ -1,68 +1,227 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.3.2 (utils/math/SafeMath.sol)
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
* @dev Returns the substraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
return a + b;
}
/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
/**

View File

@ -1,63 +1,62 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.3.2 (proxy/utils/Initializable.sol)
pragma solidity ^0.8.0;
/**
* @title Initializable
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* @dev Helper contract to support initializer functions. To use it, replace
* the constructor with a function that has the `initializer` modifier.
* WARNING: Unlike constructors, initializer functions must be manually
* invoked. This applies both to deploying an Initializable contract, as well
* as extending an Initializable contract via inheritance.
* WARNING: When used with inheritance, manual care must be taken to not invoke
* a parent initializer twice, or ensure that all initializers are idempotent,
* because this is not dealt with automatically as with constructors.
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the
* initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() initializer {}
* ```
* ====
*/
contract Initializable {
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract has been initialized.
*/
bool private initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
require(_initializing || !_initialized, "Initializable: contract is already initialized");
/**
* @dev Modifier to use in the initializer function of a contract.
*/
modifier initializer() {
require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
bool isTopLevelCall = !initializing;
if (isTopLevelCall) {
initializing = true;
initialized = true;
_;
if (isTopLevelCall) {
_initializing = false;
}
}
_;
if (isTopLevelCall) {
initializing = false;
}
}
/// @dev Returns true if and only if the function is running in the constructor
function isConstructor() private view returns (bool) {
// extcodesize checks the size of the code stored in an address, and
// address returns the current address. Since the code is still not
// deployed when running a constructor, any checks on its code size will
// yield zero, making it an effective way to detect if a contract is
// under construction or not.
address self = address(this);
uint256 cs;
assembly { cs := extcodesize(self) }
return cs == 0;
}
// Reserved storage space to allow for layout changes in the future.
uint256[50] private ______gap;
}

View File

@ -1,10 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "zeppelin/token/ERC20/IERC20.sol";
import "zeppelin/math/SafeMath.sol";
/**
@ -20,7 +19,6 @@ import "zeppelin/math/SafeMath.sol";
* compliant implementations may not do it.
*/
contract ERC20 is IERC20 {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
@ -95,7 +93,7 @@ contract ERC20 is IERC20 {
*/
function transferFrom(address from, address to, uint256 value) public override returns (bool) {
_transfer(from, to, value);
_approve(from, msg.sender, _allowed[from][msg.sender].sub(value));
_approve(from, msg.sender, _allowed[from][msg.sender] - value);
return true;
}
@ -110,7 +108,7 @@ contract ERC20 is IERC20 {
* @param addedValue The amount of tokens to increase the allowance by.
*/
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
_approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue));
_approve(msg.sender, spender, _allowed[msg.sender][spender] + addedValue);
return true;
}
@ -125,7 +123,7 @@ contract ERC20 is IERC20 {
* @param subtractedValue The amount of tokens to decrease the allowance by.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
_approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue));
_approve(msg.sender, spender, _allowed[msg.sender][spender] - subtractedValue);
return true;
}
@ -138,8 +136,8 @@ contract ERC20 is IERC20 {
function _transfer(address from, address to, uint256 value) internal {
require(to != address(0));
_balances[from] = _balances[from].sub(value);
_balances[to] = _balances[to].add(value);
_balances[from] -= value;
_balances[to] += value;
emit Transfer(from, to, value);
}
@ -153,8 +151,8 @@ contract ERC20 is IERC20 {
function _mint(address account, uint256 value) internal {
require(account != address(0));
_totalSupply = _totalSupply.add(value);
_balances[account] = _balances[account].add(value);
_totalSupply += value;
_balances[account] += value;
emit Transfer(address(0), account, value);
}
@ -167,8 +165,8 @@ contract ERC20 is IERC20 {
function _burn(address account, uint256 value) internal {
require(account != address(0));
_totalSupply = _totalSupply.sub(value);
_balances[account] = _balances[account].sub(value);
_totalSupply -= value;
_balances[account] -= value;
emit Transfer(account, address(0), value);
}
@ -196,7 +194,7 @@ contract ERC20 is IERC20 {
*/
function _burnFrom(address account, uint256 value) internal {
_burn(account, value);
_approve(account, msg.sender, _allowed[account][msg.sender].sub(value));
_approve(account, msg.sender, _allowed[account][msg.sender] - value);
}
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "./IERC20.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
/**

View File

@ -1,44 +1,99 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.3.2 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "zeppelin/token/ERC20/IERC20.sol";
import "zeppelin/math/SafeMath.sol";
import "zeppelin/utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure.
* To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
require(token.transfer(to, value));
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
require(token.transferFrom(from, to, value));
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require((value == 0) || (token.allowance(msg.sender, spender) == 0));
require(token.approve(spender, value));
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
require(token.approve(spender, newAllowance));
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value);
require(token.approve(spender, newAllowance));
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.3.2 (utils/Address.sol)
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
@ -24,14 +25,15 @@ library Address {
* ====
*/
function isContract(address account) internal view returns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
/**
@ -49,14 +51,167 @@ library Address {
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*
* _Available since v2.4.0._
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-call-value
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/Adjudicator.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
/**

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/lib/SignatureVerifier.sol";
@ -50,7 +50,7 @@ contract SignatureVerifierMock {
bytes memory _message,
bytes memory _signature,
bytes memory _publicKey,
byte _version
bytes1 _version
)
public
view
@ -61,7 +61,7 @@ contract SignatureVerifierMock {
function hashEIP191(
bytes memory _message,
byte _version
bytes1 _version
)
public
view
@ -81,30 +81,30 @@ contract UmbralDeserializerMock {
function toCapsule(bytes memory _capsuleBytes)
public pure returns (
byte pointESign,
bytes1 pointESign,
bytes32 pointEXCoord,
byte pointVSign,
bytes1 pointVSign,
bytes32 pointVXCoord,
bytes32 bnSig
)
{
UmbralDeserializer.Capsule memory capsule = _capsuleBytes.toCapsule();
pointESign = byte(capsule.pointE.sign);
pointESign = bytes1(capsule.pointE.sign);
pointEXCoord = bytes32(capsule.pointE.xCoord);
pointVSign = byte(capsule.pointV.sign);
pointVSign = bytes1(capsule.pointV.sign);
pointVXCoord = bytes32(capsule.pointV.xCoord);
bnSig = bytes32(capsule.bnSig);
}
function toCorrectnessProof(bytes memory _proofBytes)
public pure returns (
byte pointE2Sign,
bytes1 pointE2Sign,
bytes32 pointE2XCoord,
byte pointV2Sign,
bytes1 pointV2Sign,
bytes32 pointV2XCoord,
byte pointKFragCommitmentSign,
bytes1 pointKFragCommitmentSign,
bytes32 pointKFragCommitmentXCoord,
byte pointKFragPokSign,
bytes1 pointKFragPokSign,
bytes32 pointKFragPokXCoord,
bytes32 bnSig,
bytes memory kFragSignature,
@ -112,13 +112,13 @@ contract UmbralDeserializerMock {
)
{
UmbralDeserializer.CorrectnessProof memory proof = _proofBytes.toCorrectnessProof();
pointE2Sign = byte(proof.pointE2.sign);
pointE2Sign = bytes1(proof.pointE2.sign);
pointE2XCoord = bytes32(proof.pointE2.xCoord);
pointV2Sign = byte(proof.pointV2.sign);
pointV2Sign = bytes1(proof.pointV2.sign);
pointV2XCoord = bytes32(proof.pointV2.xCoord);
pointKFragCommitmentSign = byte(proof.pointKFragCommitment.sign);
pointKFragCommitmentSign = bytes1(proof.pointKFragCommitment.sign);
pointKFragCommitmentXCoord = bytes32(proof.pointKFragCommitment.xCoord);
pointKFragPokSign = byte(proof.pointKFragPok.sign);
pointKFragPokSign = bytes1(proof.pointKFragPok.sign);
pointKFragPokXCoord = bytes32(proof.pointKFragPok.xCoord);
bnSig = bytes32(proof.bnSig);
kFragSignature = proof.kFragSignature;
@ -128,13 +128,13 @@ contract UmbralDeserializerMock {
// `toCapsuleFrag` is split into two methods because of EVM stack problems with many variables
function toCorrectnessProofFromCapsuleFrag(bytes memory _cFragBytes)
public pure returns (
byte pointE2Sign,
bytes1 pointE2Sign,
bytes32 pointE2XCoord,
byte pointV2Sign,
bytes1 pointV2Sign,
bytes32 pointV2XCoord,
byte pointKFragCommitmentSign,
bytes1 pointKFragCommitmentSign,
bytes32 pointKFragCommitmentXCoord,
byte pointKFragPokSign,
bytes1 pointKFragPokSign,
bytes32 pointKFragPokXCoord,
bytes32 bnSig,
bytes memory kFragSignature,
@ -143,13 +143,13 @@ contract UmbralDeserializerMock {
{
UmbralDeserializer.CapsuleFrag memory cFrag = _cFragBytes.toCapsuleFrag();
UmbralDeserializer.CorrectnessProof memory proof = cFrag.proof;
pointE2Sign = byte(proof.pointE2.sign);
pointE2Sign = bytes1(proof.pointE2.sign);
pointE2XCoord = bytes32(proof.pointE2.xCoord);
pointV2Sign = byte(proof.pointV2.sign);
pointV2Sign = bytes1(proof.pointV2.sign);
pointV2XCoord = bytes32(proof.pointV2.xCoord);
pointKFragCommitmentSign = byte(proof.pointKFragCommitment.sign);
pointKFragCommitmentSign = bytes1(proof.pointKFragCommitment.sign);
pointKFragCommitmentXCoord = bytes32(proof.pointKFragCommitment.xCoord);
pointKFragPokSign = byte(proof.pointKFragPok.sign);
pointKFragPokSign = bytes1(proof.pointKFragPok.sign);
pointKFragPokXCoord = bytes32(proof.pointKFragPok.xCoord);
bnSig = bytes32(proof.bnSig);
kFragSignature = proof.kFragSignature;
@ -158,22 +158,22 @@ contract UmbralDeserializerMock {
function toCapsuleFrag(bytes memory _cFragBytes)
public pure returns (
byte pointE1Sign,
bytes1 pointE1Sign,
bytes32 pointE1XCoord,
byte pointV1Sign,
bytes1 pointV1Sign,
bytes32 pointV1XCoord,
bytes32 kFragId,
byte pointPrecursorSign,
bytes1 pointPrecursorSign,
bytes32 pointPrecursorXCoord
)
{
UmbralDeserializer.CapsuleFrag memory cFrag = _cFragBytes.toCapsuleFrag();
pointE1Sign = byte(cFrag.pointE1.sign);
pointE1Sign = bytes1(cFrag.pointE1.sign);
pointE1XCoord = bytes32(cFrag.pointE1.xCoord);
pointV1Sign = byte(cFrag.pointV1.sign);
pointV1Sign = bytes1(cFrag.pointV1.sign);
pointV1XCoord = bytes32(cFrag.pointV1.xCoord);
kFragId = cFrag.kFragId;
pointPrecursorSign = byte(cFrag.pointPrecursor.sign);
pointPrecursorSign = bytes1(cFrag.pointPrecursor.sign);
pointPrecursorXCoord = bytes32(cFrag.pointPrecursor.xCoord);
}
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/PolicyManager.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
/**

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
/**

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/NuCypherToken.sol";
@ -61,7 +61,7 @@ contract PolicyManagerForStakingContractMock {
function withdraw() public returns (uint256) {
uint256 value = address(this).balance;
require(value > 0);
msg.sender.transfer(value);
payable(msg.sender).transfer(value);
return value;
}
@ -96,7 +96,7 @@ contract WorkLockForStakingContractMock {
function cancelBid() external {
uint256 value = depositedETH;
depositedETH = 0;
msg.sender.transfer(value);
payable(msg.sender).transfer(value);
}
function sendCompensation() external payable {
@ -110,7 +110,7 @@ contract WorkLockForStakingContractMock {
function withdrawCompensation() external {
uint256 value = compensationValue;
compensationValue = 0;
msg.sender.transfer(value);
payable(msg.sender).transfer(value);
}
function setClaimedTokens(uint256 _claimedTokens) external {
@ -133,7 +133,7 @@ contract WorkLockForStakingContractMock {
function refund() external returns (uint256) {
uint256 value = refundETH;
refundETH = 0;
msg.sender.transfer(value);
payable(msg.sender).transfer(value);
return value;
}
@ -191,7 +191,7 @@ contract DestroyableStakingInterface {
}
function destroy() public {
selfdestruct(msg.sender);
selfdestruct(payable(msg.sender));
}
}
@ -223,7 +223,7 @@ contract SimpleStakingContract is AbstractStakingContract, Ownable {
function withdrawETH() public override onlyOwner {
uint256 balance = address(this).balance;
require(balance != 0);
msg.sender.sendValue(balance);
payable(msg.sender).sendValue(balance);
}
/**

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/StakingEscrow.sol";
@ -13,26 +13,17 @@ contract EnhancedStakingEscrow is StakingEscrow {
constructor(
NuCypherToken _token,
WorkLockInterface _workLock
WorkLockInterface _workLock,
IStaking _tStaking
)
StakingEscrow(
_token,
_workLock
_workLock,
_tStaking
)
{
}
function testSlashStaker(
address _staker,
uint256 _penalty,
address _investigator,
uint256 _reward
)
external
{
slashStaker(_staker, _penalty, _investigator, _reward);
}
function setStaker(address _staker, uint256 _value, uint16 _lastCommittedPeriod) external {
StakerInfo storage info = stakerInfo[_staker];
info.value = _value;
@ -50,11 +41,13 @@ contract StakingEscrowBad is StakingEscrow {
constructor(
NuCypherToken _token,
WorkLockInterface _workLock
WorkLockInterface _workLock,
IStaking _tStaking
)
StakingEscrow(
_token,
_workLock
_workLock,
_tStaking
)
{
}
@ -73,11 +66,13 @@ contract StakingEscrowV2Mock is StakingEscrow {
constructor(
NuCypherToken _token,
WorkLockInterface _workLock
WorkLockInterface _workLock,
IStaking _tStaking
)
StakingEscrow(
_token,
_workLock
_workLock,
_tStaking
)
{
valueToCheck = 2;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
contract OldPolicyManagerMock {

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/NuCypherToken.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "./ContractV1.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/proxy/Upgradeable.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/proxy/Upgradeable.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "./ContractV2.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/proxy/Upgradeable.sol";

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/proxy/Upgradeable.sol";
@ -34,7 +34,7 @@ contract Destroyable is Upgradeable {
}
function destroy() public {
selfdestruct(msg.sender);
selfdestruct(payable(msg.sender));
}
}

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.7.0;
pragma solidity ^0.8.0;
import "contracts/proxy/Upgradeable.sol";