solidity contracts 0.4.25 -> 0.5.3, updates openzeppelin contracts

pull/739/head
szotov 2019-02-09 16:58:09 +03:00
parent 6bd24635fa
commit 819f0951e4
35 changed files with 625 additions and 490 deletions

View File

@ -17,7 +17,7 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""Nucypher Token and Miner constants."""
ONE_YEAR_IN_SECONDS = 31540000
NUCYPHER_GAS_LIMIT = 5000000 # TODO: move elsewhere?
NUCYPHER_GAS_LIMIT = 6000000 # TODO: move elsewhere?
#
# Dispatcher

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "contracts/NuCypherToken.sol";
@ -56,7 +56,7 @@ contract Issuer is Upgradeable {
)
public
{
require(address(_token) != 0x0 &&
require(address(_token) != address(0) &&
_miningCoefficient != 0 &&
_hoursPerPeriod != 0 &&
_lockedPeriodsCoefficient != 0 &&
@ -115,10 +115,10 @@ contract Issuer is Upgradeable {
internal returns (uint256 amount)
{
uint256 currentSupply = _period <= lastMintedPeriod ?
Math.min256(currentSupply1, currentSupply2) :
Math.max256(currentSupply1, currentSupply2);
Math.min(currentSupply1, currentSupply2) :
Math.max(currentSupply1, currentSupply2);
if (currentSupply == totalSupply) {
return;
return 0;
}
//totalSupply * lockedValue * (k1 + allLockedPeriods) / (totalLockedValue * k2) -
@ -158,15 +158,15 @@ contract Issuer is Upgradeable {
}
function verifyState(address _testTarget) public onlyOwner {
require(address(delegateGet(_testTarget, "token()")) == address(token));
require(uint256(delegateGet(_testTarget, "miningCoefficient()")) == miningCoefficient);
require(uint256(delegateGet(_testTarget, "lockedPeriodsCoefficient()")) == lockedPeriodsCoefficient);
require(address(uint160(delegateGet(_testTarget, "token()"))) == address(token));
require(delegateGet(_testTarget, "miningCoefficient()") == miningCoefficient);
require(delegateGet(_testTarget, "lockedPeriodsCoefficient()") == lockedPeriodsCoefficient);
require(uint32(delegateGet(_testTarget, "secondsPerPeriod()")) == secondsPerPeriod);
require(uint16(delegateGet(_testTarget, "rewardedPeriods()")) == rewardedPeriods);
require(uint16(delegateGet(_testTarget, "lastMintedPeriod()")) == lastMintedPeriod);
require(uint256(delegateGet(_testTarget, "currentSupply1()")) == currentSupply1);
require(uint256(delegateGet(_testTarget, "currentSupply2()")) == currentSupply2);
require(uint256(delegateGet(_testTarget, "totalSupply()")) == totalSupply);
require(delegateGet(_testTarget, "currentSupply1()") == currentSupply1);
require(delegateGet(_testTarget, "currentSupply2()") == currentSupply2);
require(delegateGet(_testTarget, "totalSupply()") == totalSupply);
}
function finishUpgrade(address _target) public onlyOwner {

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "zeppelin/token/ERC20/SafeERC20.sol";
@ -208,7 +208,7 @@ contract MinersEscrow is Issuer {
* @param _values Amount of tokens to deposit for each miner
* @param _periods Amount of periods during which tokens will be locked for each miner
**/
function preDeposit(address[] _miners, uint256[] _values, uint16[] _periods)
function preDeposit(address[] memory _miners, uint256[] memory _values, uint16[] memory _periods)
public isInitialized
{
require(_miners.length != 0 &&
@ -256,13 +256,13 @@ contract MinersEscrow is Issuer {
* @param _from Miner
* @param _value Amount of tokens to deposit
* @param _tokenContract Token contract address
* @notice (param _extraData) Amount of periods during which tokens will be locked
* @param _extraData Amount of periods during which tokens will be locked
**/
function receiveApproval(
address _from,
uint256 _value,
address _tokenContract,
bytes /* _extraData */
bytes calldata _extraData
)
external
{
@ -390,7 +390,7 @@ contract MinersEscrow is Issuer {
MinerInfo storage info = minerInfo[msg.sender];
// the max locked tokens in most cases will be in the current period
// but when the miner stakes more then we should use the next period
uint256 lockedTokens = Math.max256(getLockedTokens(msg.sender, 1),
uint256 lockedTokens = Math.max(getLockedTokens(msg.sender, 1),
getLockedTokens(msg.sender, 0));
require(_value <= token.balanceOf(address(this)) &&
_value <= info.value.sub(lockedTokens));
@ -606,8 +606,8 @@ contract MinersEscrow is Issuer {
* the last values in the resulting array will be zeros addresses.
* The length of this array is always equal to the number of points.
**/
function sample(uint256[] _points, uint16 _periods)
external view returns (address[] result)
function sample(uint256[] calldata _points, uint16 _periods)
external view returns (address[] memory result)
{
require(_periods > 0 && _points.length > 0);
uint16 currentPeriod = getCurrentPeriod();
@ -646,7 +646,7 @@ contract MinersEscrow is Issuer {
* @notice Set policy manager address
**/
function setPolicyManager(PolicyManagerInterface _policyManager) external onlyOwner {
require(address(policyManager) == 0x0 &&
require(address(policyManager) == address(0) &&
_policyManager.escrow() == address(this));
policyManager = _policyManager;
}
@ -703,10 +703,10 @@ contract MinersEscrow is Issuer {
/**
* @dev Get MinerInfo structure by delegatecall
**/
function delegateGetMinerInfo(address _target, address _miner)
function delegateGetMinerInfo(address _target, bytes32 _miner)
internal returns (MinerInfo memory result)
{
bytes32 memoryAddress = delegateGetData(_target, "minerInfo(address)", 1, bytes32(_miner), 0);
bytes32 memoryAddress = delegateGetData(_target, "minerInfo(address)", 1, _miner, 0);
assembly {
result := memoryAddress
}
@ -715,11 +715,11 @@ contract MinersEscrow is Issuer {
/**
* @dev Get StakeInfo structure by delegatecall
**/
function delegateGetStakeInfo(address _target, address _miner, uint256 _index)
function delegateGetStakeInfo(address _target, bytes32 _miner, uint256 _index)
internal returns (StakeInfo memory result)
{
bytes32 memoryAddress = delegateGetData(
_target, "getStakeInfo(address,uint256)", 2, bytes32(_miner), bytes32(_index));
_target, "getStakeInfo(address,uint256)", 2, _miner, bytes32(_index));
assembly {
result := memoryAddress
}
@ -728,11 +728,11 @@ contract MinersEscrow is Issuer {
/**
* @dev Get Downtime structure by delegatecall
**/
function delegateGetPastDowntime(address _target, address _miner, uint256 _index)
function delegateGetPastDowntime(address _target, bytes32 _miner, uint256 _index)
internal returns (Downtime memory result)
{
bytes32 memoryAddress = delegateGetData(
_target, "getPastDowntime(address,uint256)", 2, bytes32(_miner), bytes32(_index));
_target, "getPastDowntime(address,uint256)", 2, _miner, bytes32(_index));
assembly {
result := memoryAddress
}
@ -742,41 +742,41 @@ contract MinersEscrow is Issuer {
super.verifyState(_testTarget);
require(uint16(delegateGet(_testTarget, "minLockedPeriods()")) ==
minLockedPeriods);
require(uint256(delegateGet(_testTarget, "minAllowableLockedTokens()")) ==
require(delegateGet(_testTarget, "minAllowableLockedTokens()") ==
minAllowableLockedTokens);
require(uint256(delegateGet(_testTarget, "maxAllowableLockedTokens()")) ==
require(delegateGet(_testTarget, "maxAllowableLockedTokens()") ==
maxAllowableLockedTokens);
require(address(delegateGet(_testTarget, "policyManager()")) == address(policyManager));
require(uint256(delegateGet(_testTarget, "lockedPerPeriod(uint16)",
bytes32(RESERVED_PERIOD))) == lockedPerPeriod[RESERVED_PERIOD]);
require(address(uint160(delegateGet(_testTarget, "policyManager()"))) == address(policyManager));
require(delegateGet(_testTarget, "lockedPerPeriod(uint16)",
bytes32(bytes2(RESERVED_PERIOD))) == lockedPerPeriod[RESERVED_PERIOD]);
require(uint256(delegateGet(_testTarget, "getMinersLength()")) == miners.length);
require(delegateGet(_testTarget, "getMinersLength()") == miners.length);
if (miners.length == 0) {
return;
}
address minerAddress = miners[0];
bytes32 miner = bytes32(minerAddress);
require(address(delegateGet(_testTarget, "miners(uint256)", 0)) == minerAddress);
require(address(uint160(delegateGet(_testTarget, "miners(uint256)", 0))) == minerAddress);
MinerInfo storage info = minerInfo[minerAddress];
MinerInfo memory infoToCheck = delegateGetMinerInfo(_testTarget, minerAddress);
bytes32 miner = bytes32(uint256(minerAddress));
MinerInfo memory infoToCheck = delegateGetMinerInfo(_testTarget, miner);
require(infoToCheck.value == info.value &&
infoToCheck.confirmedPeriod1 == info.confirmedPeriod1 &&
infoToCheck.confirmedPeriod2 == info.confirmedPeriod2 &&
infoToCheck.lastActivePeriod == info.lastActivePeriod);
require(uint256(delegateGet(_testTarget, "getPastDowntimeLength(address)", miner)) ==
require(delegateGet(_testTarget, "getPastDowntimeLength(address)", miner) ==
info.pastDowntime.length);
for (i = 0; i < info.pastDowntime.length && i < MAX_CHECKED_VALUES; i++) {
for (uint256 i = 0; i < info.pastDowntime.length && i < MAX_CHECKED_VALUES; i++) {
Downtime storage downtime = info.pastDowntime[i];
Downtime memory downtimeToCheck = delegateGetPastDowntime(_testTarget, minerAddress, i);
Downtime memory downtimeToCheck = delegateGetPastDowntime(_testTarget, miner, i);
require(downtimeToCheck.startPeriod == downtime.startPeriod &&
downtimeToCheck.endPeriod == downtime.endPeriod);
}
require(uint256(delegateGet(_testTarget, "getStakesLength(address)", miner)) == info.stakes.length);
require(delegateGet(_testTarget, "getStakesLength(address)", miner) == info.stakes.length);
for (uint256 i = 0; i < info.stakes.length && i < MAX_CHECKED_VALUES; i++) {
StakeInfo storage stakeInfo = info.stakes[i];
StakeInfo memory stakeInfoToCheck = delegateGetStakeInfo(_testTarget, minerAddress, i);
StakeInfo memory stakeInfoToCheck = delegateGetStakeInfo(_testTarget, miner, i);
require(stakeInfoToCheck.firstPeriod == stakeInfo.firstPeriod &&
stakeInfoToCheck.lastPeriod == stakeInfo.lastPeriod &&
stakeInfoToCheck.periods == stakeInfo.periods &&

View File

@ -1,9 +1,8 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "zeppelin/token/ERC20/BurnableToken.sol";
import "zeppelin/token/ERC20/StandardToken.sol";
import "zeppelin/token/ERC20/DetailedERC20.sol";
import "zeppelin/token/ERC20/ERC20.sol";
import "zeppelin/token/ERC20/ERC20Detailed.sol";
/**
@ -11,16 +10,14 @@ import "zeppelin/token/ERC20/DetailedERC20.sol";
* @notice ERC20 token which can be burned by their owners
* @dev Optional approveAndCall() functionality to notify a contract if an approve() has occurred.
**/
contract NuCypherToken is StandardToken, DetailedERC20('NuCypher', 'NU', 18), BurnableToken {
contract NuCypherToken is ERC20, ERC20Detailed('NuCypher', 'NU', 18) {
/**
* @notice Set amount of tokens
* @param _initialAmount Initial amount of tokens
**/
constructor (uint256 _initialAmount) public {
balances[msg.sender] = _initialAmount;
totalSupply_ = _initialAmount;
emit Transfer(0x0, msg.sender, _initialAmount);
_mint(msg.sender, _initialAmount);
}
/**
@ -29,7 +26,7 @@ contract NuCypherToken is StandardToken, DetailedERC20('NuCypher', 'NU', 18), Bu
* @dev call the receiveApproval function on the contract you want to be notified.
* receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData)
**/
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
function approveAndCall(address _spender, uint256 _value, bytes memory _extraData)
public returns (bool success)
{
approve(_spender, _value);
@ -52,6 +49,6 @@ contract TokenRecipient {
* @param _tokenContract Address of the token contract
* @param _extraData Extra data
**/
function receiveApproval(address _from, uint256 _value, address _tokenContract, bytes _extraData) external;
function receiveApproval(address _from, uint256 _value, address _tokenContract, bytes calldata _extraData) external;
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "zeppelin/token/ERC20/SafeERC20.sol";
@ -80,7 +80,7 @@ contract PolicyManager is Upgradeable {
}
bytes16 constant RESERVED_POLICY_ID = bytes16(0);
address constant RESERVED_NODE = 0x0;
address constant RESERVED_NODE = address(0);
MinersEscrow public escrow;
uint32 public secondsPerPeriod;
@ -92,7 +92,7 @@ contract PolicyManager is Upgradeable {
* @param _escrow Escrow contract
**/
constructor(MinersEscrow _escrow) public {
require(address(_escrow) != 0x0);
require(address(_escrow) != address(0));
escrow = _escrow;
secondsPerPeriod = escrow.secondsPerPeriod();
}
@ -145,7 +145,7 @@ contract PolicyManager is Upgradeable {
bytes16 _policyId,
uint16 _numberOfPeriods,
uint256 _firstPartialReward,
address[] _nodes
address[] memory _nodes
)
public payable
{
@ -210,7 +210,7 @@ contract PolicyManager is Upgradeable {
* @notice Withdraw reward by node
* @param _recipient Recipient of the reward
**/
function withdraw(address _recipient) public returns (uint256) {
function withdraw(address payable _recipient) public returns (uint256) {
NodeInfo storage node = nodes[msg.sender];
uint256 reward = node.reward;
require(reward != 0);
@ -264,7 +264,7 @@ contract PolicyManager is Upgradeable {
if (lastActivePeriod < _policy.startPeriod - 1) {
refundValue = _policy.firstPartialReward;
} else if (_arrangement.indexOfDowntimePeriods < length) {
(startPeriod, endPeriod) = escrow.getPastDowntime(
(uint16 startPeriod, uint16 endPeriod) = escrow.getPastDowntime(
_arrangement.node, _arrangement.indexOfDowntimePeriods);
if (_policy.startPeriod > startPeriod && _policy.startPeriod - 1 <= endPeriod) {
refundValue = _policy.firstPartialReward;
@ -288,7 +288,8 @@ contract PolicyManager is Upgradeable {
require(policy.client == msg.sender && !policy.disabled);
uint16 endPeriod = policy.lastPeriod.add16(1);
uint256 numberOfActive = policy.arrangements.length;
for (uint256 i = 0; i < policy.arrangements.length; i++) {
uint256 i = 0;
for (; i < policy.arrangements.length; i++) {
ArrangementInfo storage arrangement = policy.arrangements[i];
address node = arrangement.node;
if (node == RESERVED_NODE || _node != RESERVED_NODE && _node != node) {
@ -345,7 +346,8 @@ contract PolicyManager is Upgradeable {
{
Policy storage policy = policies[_policyId];
require(msg.sender == policy.client && !policy.disabled);
for (uint256 i = 0; i < policy.arrangements.length; i++) {
uint256 i = 0;
for (; i < policy.arrangements.length; i++) {
ArrangementInfo storage arrangement = policy.arrangements[i];
if (arrangement.node == RESERVED_NODE || _node != RESERVED_NODE && _node != arrangement.node) {
continue;
@ -491,14 +493,14 @@ contract PolicyManager is Upgradeable {
function delegateGetNodeInfo(address _target, address _node)
internal returns (NodeInfo memory result)
{
bytes32 memoryAddress = delegateGetData(_target, "nodes(address)", 1, bytes32(_node), 0);
bytes32 memoryAddress = delegateGetData(_target, "nodes(address)", 1, bytes32(uint256(_node)), 0);
assembly {
result := memoryAddress
}
}
function verifyState(address _testTarget) public onlyOwner {
require(address(delegateGet(_testTarget, "escrow()")) == address(escrow));
require(address(uint160(delegateGet(_testTarget, "escrow()"))) == address(escrow));
require(uint32(delegateGet(_testTarget, "secondsPerPeriod()")) == secondsPerPeriod);
Policy storage policy = policies[RESERVED_POLICY_ID];
Policy memory policyToCheck = delegateGetPolicy(_testTarget, RESERVED_POLICY_ID);
@ -509,8 +511,8 @@ contract PolicyManager is Upgradeable {
policyToCheck.lastPeriod == policy.lastPeriod &&
policyToCheck.disabled == policy.disabled);
require(uint256(delegateGet(_testTarget, "getArrangementsLength(bytes16)",
RESERVED_POLICY_ID)) == policy.arrangements.length);
require(delegateGet(_testTarget, "getArrangementsLength(bytes16)",
RESERVED_POLICY_ID) == policy.arrangements.length);
ArrangementInfo storage arrangement = policy.arrangements[0];
ArrangementInfo memory arrangementToCheck = delegateGetArrangementInfo(
_testTarget, RESERVED_POLICY_ID, 0);
@ -526,7 +528,7 @@ contract PolicyManager is Upgradeable {
nodeInfoToCheck.minRewardRate == nodeInfo.minRewardRate);
require(int256(delegateGet(_testTarget, "getNodeRewardDelta(address,uint16)",
bytes32(RESERVED_NODE), 11)) == nodeInfo.rewardDelta[11]);
bytes32(bytes20(RESERVED_NODE)), bytes32(uint256(11)))) == nodeInfo.rewardDelta[11]);
}
function finishUpgrade(address _target) public onlyOwner {
@ -535,7 +537,7 @@ contract PolicyManager is Upgradeable {
secondsPerPeriod = policyManager.secondsPerPeriod();
// Create fake Policy and NodeInfo to use them in verifyState(address)
Policy storage policy = policies[RESERVED_POLICY_ID];
policy.client = owner;
policy.client = owner();
policy.startPeriod = 1;
policy.lastPeriod = 2;
policy.rewardRate = 3;

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "zeppelin/ownership/Ownable.sol";
@ -40,12 +40,13 @@ contract Seeder is Ownable {
* @param _ip IPv4 address of the seed node
* @param _port TCP port of the seed node
**/
function enroll(address _seed, string _ip, uint16 _port) public onlyOwner {
function enroll(address _seed, string memory _ip, uint16 _port) public onlyOwner {
seeds[_seed] = SeedInfo(_ip, _port);
for (uint256 i = 0; i < seedArray.length; i++) {
uint256 i = 0;
for (; i < seedArray.length; i++) {
address currentSeed = seedArray[i];
if (currentSeed == 0x0) {
if (currentSeed == address(0)) {
seedArray[i] = _seed;
break;
} else if (currentSeed == _seed) {
@ -61,8 +62,8 @@ contract Seeder is Ownable {
* @param _ip Updated IPv4 address of the existing seed node
* @param _port Updated TCP port of the existing seed node
**/
function refresh(string _ip, uint16 _port) public {
SeedInfo seed = seeds[msg.sender];
function refresh(string memory _ip, uint16 _port) public {
SeedInfo storage seed = seeds[msg.sender];
require(seed.port != 0);
seed.ip = _ip;
seed.port = _port;

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "zeppelin/ownership/Ownable.sol";
@ -20,7 +20,7 @@ contract UserEscrowLibraryLinker is Ownable {
* @param _newSecretHash Secret hash (keccak256)
**/
constructor(address _target, bytes32 _newSecretHash) public {
require(_target != 0x0);
require(_target != address(0));
target = _target;
secretHash = _newSecretHash;
}
@ -31,8 +31,8 @@ contract UserEscrowLibraryLinker is Ownable {
* @param _secret Secret for proof of contract owning
* @param _newSecretHash New secret hash (keccak256)
**/
function upgrade(address _target, bytes _secret, bytes32 _newSecretHash) public onlyOwner {
require(_target != 0x0);
function upgrade(address _target, bytes memory _secret, bytes32 _newSecretHash) public onlyOwner {
require(_target != address(0));
require(keccak256(_secret) == secretHash && _newSecretHash != secretHash);
target = _target;
secretHash = _newSecretHash;
@ -64,7 +64,7 @@ contract UserEscrow is Ownable {
* @param _token Token contract
**/
constructor(UserEscrowLibraryLinker _linker, NuCypherToken _token) public {
require(address(_token) != 0x0 && address(_linker) != 0x0);
require(address(_token) != address(0) && address(_linker) != address(0));
linker = _linker;
token = _token;
}
@ -98,8 +98,8 @@ contract UserEscrow is Ownable {
**/
function withdrawTokens(uint256 _value) public onlyOwner {
require(token.balanceOf(address(this)).sub(getLockedTokens()) >= _value);
token.safeTransfer(owner, _value);
emit TokensWithdrawn(owner, _value);
token.safeTransfer(msg.sender, _value);
emit TokensWithdrawn(msg.sender, _value);
}
/**
@ -108,17 +108,17 @@ contract UserEscrow is Ownable {
function withdrawETH() public onlyOwner {
uint256 balance = address(this).balance;
require(balance != 0);
owner.transfer(balance);
emit ETHWithdrawn(owner, balance);
msg.sender.transfer(balance);
emit ETHWithdrawn(msg.sender, balance);
}
/**
* @dev Fallback function send all requests to the target proxy contract
**/
function () public payable onlyOwner {
function () external payable onlyOwner {
address libraryTarget = linker.target();
require(libraryTarget != 0x0);
bool callSuccess = libraryTarget.delegatecall(msg.data);
require(libraryTarget != address(0));
(bool callSuccess,) = libraryTarget.delegatecall(msg.data);
if (callSuccess) {
assembly {
returndatacopy(0x0, 0x0, returndatasize)

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "./UserEscrow.sol";
@ -40,9 +40,9 @@ contract UserEscrowProxy {
)
public
{
require(address(_token) != 0x0 &&
address(_escrow) != 0x0 &&
address(_policyManager) != 0x0);
require(address(_token) != address(0) &&
address(_escrow) != address(0) &&
address(_policyManager) != address(0));
token = _token;
escrow = _escrow;
policyManager = _policyManager;
@ -53,7 +53,8 @@ contract UserEscrowProxy {
* @dev Assume that `this` is the UserEscrow contract
**/
function getStateContract() internal view returns (UserEscrowProxy) {
UserEscrowLibraryLinker linker = UserEscrow(address(this)).linker();
address payable userEscrowAddress = address(bytes20(address(this)));
UserEscrowLibraryLinker linker = UserEscrow(userEscrowAddress).linker();
return UserEscrowProxy(linker.target());
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "zeppelin/math/SafeMath.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.23;
pragma solidity ^0.5.3;
import "./Upgradeable.sol";
@ -19,11 +19,12 @@ contract Dispatcher is Upgradeable {
* @param _newSecretHash Secret hash (keccak256)
**/
constructor(address _target, bytes32 _newSecretHash) public {
require(_target != 0x0);
require(_target != address(0));
target = _target;
secretHash = _newSecretHash;
require(target.delegatecall(bytes4(keccak256("finishUpgrade(address)")), target));
emit Upgraded(0x0, _target, msg.sender);
(bool callSuccess,) = target.delegatecall(abi.encodeWithSignature("finishUpgrade(address)", target));
require(callSuccess);
emit Upgraded(address(0), _target, msg.sender);
}
/**
@ -32,23 +33,24 @@ contract Dispatcher is Upgradeable {
* @param _secret Secret for proof of contract owning
* @param _newSecretHash New secret hash (keccak256)
**/
function upgrade(address _target, bytes _secret, bytes32 _newSecretHash) public onlyOwner {
function upgrade(address _target, bytes memory _secret, bytes32 _newSecretHash) public onlyOwner {
require(keccak256(_secret) == secretHash && _newSecretHash != secretHash);
verifyState(_target);
verifyUpgradeableState(target, _target);
previousTarget = target;
target = _target;
secretHash = _newSecretHash;
require(target.delegatecall(bytes4(keccak256("finishUpgrade(address)")), target));
(bool callSuccess,) = target.delegatecall(abi.encodeWithSignature("finishUpgrade(address)", target));
require(callSuccess);
emit Upgraded(previousTarget, _target, msg.sender);
}
function verifyState(address _testTarget) public onlyOwner {
//checks equivalence accessing target through new contract and current storage
require(address(delegateGet(_testTarget, "owner()")) == owner);
require(address(delegateGet(_testTarget, "target()")) == target);
require(address(delegateGet(_testTarget, "previousTarget()")) == previousTarget);
require(delegateGet(_testTarget, "secretHash()") == secretHash);
require(address(uint160(delegateGet(_testTarget, "owner()"))) == owner());
require(address(uint160(delegateGet(_testTarget, "target()"))) == target);
require(address(uint160(delegateGet(_testTarget, "previousTarget()"))) == previousTarget);
require(bytes32(delegateGet(_testTarget, "secretHash()")) == secretHash);
}
/**
@ -57,22 +59,24 @@ contract Dispatcher is Upgradeable {
* @param _secret Secret for proof of contract owning
* @param _newSecretHash New secret hash (keccak256)
**/
function rollback(bytes _secret, bytes32 _newSecretHash) public onlyOwner {
require(previousTarget != 0x0);
function rollback(bytes memory _secret, bytes32 _newSecretHash) public onlyOwner {
require(previousTarget != address(0));
require(keccak256(_secret) == secretHash && _newSecretHash != secretHash);
emit RolledBack(target, previousTarget, msg.sender);
verifyUpgradeableState(previousTarget, target);
target = previousTarget;
previousTarget = 0x0;
previousTarget = address(0);
secretHash = _newSecretHash;
require(target.delegatecall(bytes4(keccak256("finishUpgrade(address)")), target));
(bool callSuccess,) = target.delegatecall(abi.encodeWithSignature("finishUpgrade(address)", target));
require(callSuccess);
}
/**
* @dev Call verifyState method for Upgradeable contract
**/
function verifyUpgradeableState(address _from, address _to) internal {
require(_from.delegatecall(bytes4(keccak256("verifyState(address)")), _to));
(bool callSuccess,) = _from.delegatecall(abi.encodeWithSignature("verifyState(address)", _to));
require(callSuccess);
}
function finishUpgrade(address) public {}
@ -81,9 +85,9 @@ contract Dispatcher is Upgradeable {
* @dev Fallback function send all requests to the target contract.
* If contract not exists then result will be unpredictable (see DELEGATECALL)
**/
function () public payable {
assert(target != 0x0);
bool callSuccess = target.delegatecall(msg.data);
function () external payable {
assert(target != address(0));
(bool callSuccess,) = target.delegatecall(msg.data);
if (callSuccess) {
assembly {
returndatacopy(0x0, 0x0, returndatasize)

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.23;
pragma solidity ^0.5.3;
import "zeppelin/ownership/Ownable.sol";
@ -53,7 +53,7 @@ contract Upgradeable is Ownable {
**/
function delegateGetData(
address _target,
string _signature,
string memory _signature,
uint8 _numberOfArguments,
bytes32 _argument1,
bytes32 _argument2
@ -85,8 +85,8 @@ contract Upgradeable is Ownable {
* @dev Call "getter" without parameters.
* Result should not exceed 32 bytes
**/
function delegateGet(address _target, string _signature)
internal returns (bytes32 result)
function delegateGet(address _target, string memory _signature)
internal returns (uint256 result)
{
bytes32 memoryAddress = delegateGetData(_target, _signature, 0, 0, 0);
assembly {
@ -98,8 +98,8 @@ contract Upgradeable is Ownable {
* @dev Call "getter" with one parameter.
* Result should not exceed 32 bytes
**/
function delegateGet(address _target, string _signature, bytes32 _argument)
internal returns (bytes32 result)
function delegateGet(address _target, string memory _signature, bytes32 _argument)
internal returns (uint256 result)
{
bytes32 memoryAddress = delegateGetData(_target, _signature, 1, _argument, 0);
assembly {
@ -113,11 +113,11 @@ contract Upgradeable is Ownable {
**/
function delegateGet(
address _target,
string _signature,
string memory _signature,
bytes32 _argument1,
bytes32 _argument2
)
internal returns (bytes32 result)
internal returns (uint256 result)
{
bytes32 memoryAddress = delegateGetData(_target, _signature, 2, _argument1, _argument2);
assembly {

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.23;
pragma solidity ^0.5.3;
/**
@ -6,19 +6,27 @@ pragma solidity ^0.4.23;
* @dev Assorted math operations
*/
library Math {
function max64(uint64 a, uint64 b) internal pure returns (uint64) {
return a >= b ? a : b;
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
function min64(uint64 a, uint64 b) internal pure returns (uint64) {
return a < b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function max256(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
function min256(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @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.
*/
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);
}
}

View File

@ -1,48 +1,66 @@
pragma solidity ^0.4.23;
pragma solidity ^0.5.3;
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
* @dev Unsigned math operations with safety checks that revert on error
*/
library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
*/
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;
}
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
uint256 c = a * b;
require(c / a == b);
return c;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
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
/**
* @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
return c;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.23;
pragma solidity ^0.5.3;
/**
@ -7,36 +7,67 @@ pragma solidity ^0.4.23;
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor () internal {
_owner = msg.sender;
emit OwnershipTransferred(address(0), _owner);
}
/**
* @return the address of the owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner());
_;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @return true if `msg.sender` is the owner of the contract.
*/
function isOwner() public view returns (bool) {
return msg.sender == _owner;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
/**
* @dev Allows the current owner to relinquish control of the contract.
* @notice Renouncing to ownership will leave the contract without an owner.
* It will not be possible to call the functions with the `onlyOwner`
* modifier anymore.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0));
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}

View File

@ -1,52 +0,0 @@
pragma solidity ^0.4.23;
import "./ERC20Basic.sol";
import "../../math/SafeMath.sol";
/**
* @title Basic token
* @dev Basic version of StandardToken, with no allowances.
*/
contract BasicToken is ERC20Basic {
using SafeMath for uint256;
mapping(address => uint256) balances;
uint256 totalSupply_;
/**
* @dev total number of tokens in existence
*/
function totalSupply() public view returns (uint256) {
return totalSupply_;
}
/**
* @dev transfer token for a specified address
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
*/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[msg.sender]);
// SafeMath.sub will throw if there is not enough balance.
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
emit Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public view returns (uint256 balance) {
return balances[_owner];
}
}

View File

@ -1,29 +0,0 @@
pragma solidity ^0.4.23;
import "./BasicToken.sol";
/**
* @title Burnable Token
* @dev Token that can be irreversibly burned (destroyed).
*/
contract BurnableToken is BasicToken {
event Burn(address indexed burner, uint256 value);
/**
* @dev Burns a specific amount of tokens.
* @param _value The amount of token to be burned.
*/
function burn(uint256 _value) public {
require(_value <= balances[msg.sender]);
// no need to require value <= totalSupply, since that would imply the
// sender's balance is greater than the totalSupply, which *should* be an assertion failure
address burner = msg.sender;
balances[burner] = balances[burner].sub(_value);
totalSupply_ = totalSupply_.sub(_value);
emit Burn(burner, _value);
emit Transfer(burner, address(0), _value);
}
}

View File

@ -1,16 +0,0 @@
pragma solidity ^0.4.23;
import "./ERC20.sol";
contract DetailedERC20 is ERC20 {
string public name;
string public symbol;
uint8 public decimals;
constructor(string _name, string _symbol, uint8 _decimals) public {
name = _name;
symbol = _symbol;
decimals = _decimals;
}
}

View File

@ -1,15 +1,200 @@
pragma solidity ^0.4.23;
pragma solidity ^0.5.3;
import "./ERC20Basic.sol";
import "./IERC20.sol";
import "../../math/SafeMath.sol";
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
* Originally based on code by FirstBlood:
* https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*
* This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for
* all accounts just by listening to said events. Note that this isn't required by the specification, and other
* compliant implementations may not do it.
*/
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) public view returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Approval(address indexed owner, address indexed spender, uint256 value);
contract ERC20 is IERC20 {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowed;
uint256 private _totalSupply;
/**
* @dev Total number of tokens in existence
*/
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
/**
* @dev Gets the balance of the specified address.
* @param owner The address to query the balance of.
* @return An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address owner) public view returns (uint256) {
return _balances[owner];
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param owner address The address which owns the funds.
* @param spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(address owner, address spender) public view returns (uint256) {
return _allowed[owner][spender];
}
/**
* @dev Transfer token for a specified address
* @param to The address to transfer to.
* @param value The amount to be transferred.
*/
function transfer(address to, uint256 value) public returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
*/
function approve(address spender, uint256 value) public returns (bool) {
// To change the approve amount you first have to reduce the addresses`
// allowance to zero by calling `approve(_spender, 0)` if it is not
// already 0 to mitigate the race condition described here:
// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
require(value == 0 || _allowed[msg.sender][spender] == 0);
_approve(msg.sender, spender, value);
return true;
}
/**
* @dev Transfer tokens from one address to another.
* Note that while this function emits an Approval event, this is not required as per the specification,
* and other compliant implementations may not emit the event.
* @param from address The address which you want to send tokens from
* @param to address The address which you want to transfer to
* @param value uint256 the amount of tokens to be transferred
*/
function transferFrom(address from, address to, uint256 value) public returns (bool) {
_transfer(from, to, value);
_approve(from, msg.sender, _allowed[from][msg.sender].sub(value));
return true;
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
* approve should be called when allowed_[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* Emits an Approval event.
* @param spender The address which will spend the funds.
* @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));
return true;
}
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
* approve should be called when allowed_[_spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* Emits an Approval event.
* @param spender The address which will spend the funds.
* @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));
return true;
}
/**
* @dev Transfer token for a specified addresses
* @param from The address to transfer from.
* @param to The address to transfer to.
* @param value The amount to be transferred.
*/
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);
emit Transfer(from, to, value);
}
/**
* @dev Internal function that mints an amount of the token and assigns it to
* an account. This encapsulates the modification of balances such that the
* proper events are emitted.
* @param account The account that will receive the created tokens.
* @param value The amount that will be created.
*/
function _mint(address account, uint256 value) internal {
require(account != address(0));
_totalSupply = _totalSupply.add(value);
_balances[account] = _balances[account].add(value);
emit Transfer(address(0), account, value);
}
/**
* @dev Internal function that burns an amount of the token of a given
* account.
* @param account The account whose tokens will be burnt.
* @param value The amount that will be burnt.
*/
function _burn(address account, uint256 value) internal {
require(account != address(0));
_totalSupply = _totalSupply.sub(value);
_balances[account] = _balances[account].sub(value);
emit Transfer(account, address(0), value);
}
/**
* @dev Approve an address to spend another addresses' tokens.
* @param owner The address that owns the tokens.
* @param spender The address that will spend the tokens.
* @param value The number of tokens that can be spent.
*/
function _approve(address owner, address spender, uint256 value) internal {
require(spender != address(0));
require(owner != address(0));
_allowed[owner][spender] = value;
emit Approval(owner, spender, value);
}
/**
* @dev Internal function that burns an amount of the token of a given
* account, deducting from the sender's allowance for said account. Uses the
* internal burn function.
* Emits an Approval event (reflecting the reduced allowance).
* @param account The account whose tokens will be burnt.
* @param value The amount that will be burnt.
*/
function _burnFrom(address account, uint256 value) internal {
_burn(account, value);
_approve(account, msg.sender, _allowed[account][msg.sender].sub(value));
}
}

View File

@ -1,14 +0,0 @@
pragma solidity ^0.4.23;
/**
* @title ERC20Basic
* @dev Simpler version of ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/179
*/
contract ERC20Basic {
function totalSupply() public view returns (uint256);
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}

View File

@ -0,0 +1,44 @@
pragma solidity ^0.5.3;
import "./IERC20.sol";
/**
* @title ERC20Detailed token
* @dev The decimals are only for visualization purposes.
* All the operations are done using the smallest and indivisible token unit,
* just as on Ethereum all the operations are done in wei.
*/
contract ERC20Detailed is IERC20 {
string private _name;
string private _symbol;
uint8 private _decimals;
constructor (string memory name, string memory symbol, uint8 decimals) public {
_name = name;
_symbol = symbol;
_decimals = decimals;
}
/**
* @return the name of the token.
*/
function name() public view returns (string memory) {
return _name;
}
/**
* @return the symbol of the token.
*/
function symbol() public view returns (string memory) {
return _symbol;
}
/**
* @return the number of decimals of the token.
*/
function decimals() public view returns (uint8) {
return _decimals;
}
}

View File

@ -0,0 +1,24 @@
pragma solidity ^0.5.3;
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
interface IERC20 {
function transfer(address to, uint256 value) external returns (bool);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function totalSupply() external view returns (uint256);
function balanceOf(address who) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}

View File

@ -1,7 +1,8 @@
pragma solidity ^0.4.23;
pragma solidity ^0.5.3;
import "./ERC20Basic.sol";
import "./ERC20.sol";
import "./IERC20.sol";
import "../../math/SafeMath.sol";
/**
@ -11,15 +12,31 @@ import "./ERC20.sol";
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
function safeTransfer(ERC20Basic token, address to, uint256 value) internal {
assert(token.transfer(to, value));
}
using SafeMath for uint256;
function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal {
assert(token.transferFrom(from, to, value));
}
function safeTransfer(IERC20 token, address to, uint256 value) internal {
require(token.transfer(to, value));
}
function safeApprove(ERC20 token, address spender, uint256 value) internal {
assert(token.approve(spender, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
require(token.transferFrom(from, to, value));
}
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));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
require(token.approve(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));
}
}

View File

@ -1,100 +0,0 @@
pragma solidity ^0.4.23;
import "./BasicToken.sol";
import "./ERC20.sol";
/**
* @title Standard ERC20 token
*
* @dev Implementation of the basic standard token.
* @dev https://github.com/ethereum/EIPs/issues/20
* @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
*/
contract StandardToken is ERC20, BasicToken {
mapping (address => mapping (address => uint256)) internal allowed;
/**
* @dev Transfer tokens from one address to another
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
*/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
*
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
*/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param _owner address The address which owns the funds.
* @param _spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(address _owner, address _spender) public view returns (uint256) {
return allowed[_owner][_spender];
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
*
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _addedValue The amount of tokens to increase the allowance by.
*/
function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
*
* approve should be called when allowed[_spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _subtractedValue The amount of tokens to decrease the allowance by.
*/
function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
uint oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "contracts/Issuer.sol";
@ -100,7 +100,7 @@ contract IssuerV2Mock is Issuer {
function verifyState(address _testTarget) public onlyOwner {
super.verifyState(_testTarget);
require(uint256(delegateGet(_testTarget, "valueToCheck()")) == valueToCheck);
require(delegateGet(_testTarget, "valueToCheck()") == valueToCheck);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "contracts/MinersEscrow.sol";
@ -80,7 +80,7 @@ contract MinersEscrowV2Mock is MinersEscrow {
function verifyState(address _testTarget) public onlyOwner {
super.verifyState(_testTarget);
require(uint256(delegateGet(_testTarget, "valueToCheck()")) == valueToCheck);
require(delegateGet(_testTarget, "valueToCheck()") == valueToCheck);
}
function finishUpgrade(address _target) public onlyOwner {

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "contracts/PolicyManager.sol";
@ -36,7 +36,7 @@ contract PolicyManagerV2Mock is PolicyManager {
function verifyState(address _testTarget) public onlyOwner {
super.verifyState(_testTarget);
require(uint256(delegateGet(_testTarget, "valueToCheck()")) == valueToCheck);
require(delegateGet(_testTarget, "valueToCheck()") == valueToCheck);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
/**
@ -15,7 +15,7 @@ contract ReceiveApprovalMethodMock {
address _from,
uint256 _value,
address _tokenContract,
bytes _extraData
bytes calldata _extraData
)
external
{

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "contracts/NuCypherToken.sol";
@ -71,7 +71,7 @@ contract PolicyManagerForUserEscrowMock {
uint256 public minRewardRate;
function withdraw(address _recipient) public returns (uint256) {
function withdraw(address payable _recipient) public returns (uint256) {
uint256 value = address(this).balance;
require(value > 0);
_recipient.transfer(value);
@ -86,7 +86,7 @@ contract PolicyManagerForUserEscrowMock {
minRewardRate = _minRewardRate;
}
function () public payable {}
function () external payable {}
}
@ -109,7 +109,7 @@ contract UserEscrowLibraryMockV1 {
**/
contract UserEscrowLibraryMockV2 {
function () public payable {
function () external payable {
// can only use with ETH
require(msg.value > 0);
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "./ContractInterface.sol";
@ -38,8 +38,8 @@ contract ContractV2Bad is ContractInterface, Upgradeable {
return storageValue;
}
function setDynamicallySizedValue(string) public {}
function getDynamicallySizedValue() public view returns (string) {}
function setDynamicallySizedValue(string memory) public {}
function getDynamicallySizedValue() public view returns (string memory) {}
function pushArrayValue(uint) public {}
function getArrayValue(uint _index) public view returns (uint) {

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
// Note we don't need to use this interface (although it is advised if it's unlikely it will change).
// We can cast the UpgradableContractProxy as the specific implementations eg ContractV1.sol or ContractV2.sol.
@ -13,8 +13,8 @@ contract ContractInterface {
function setStorageValue(uint _value) public;
function getStorageValue() public view returns (uint);
function setDynamicallySizedValue(string _dynamicValue) public;
function getDynamicallySizedValue() public view returns (string);
function setDynamicallySizedValue(string memory _dynamicValue) public;
function getDynamicallySizedValue() public view returns (string memory);
function pushArrayValue(uint _value) public;
function getArrayValue(uint _index) public view returns (uint);

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "./ContractInterface.sol";
@ -56,10 +56,10 @@ contract ContractV1 is ContractInterface, Upgradeable {
return storageValue;
}
function setDynamicallySizedValue(string _dynamicValue) public {
function setDynamicallySizedValue(string memory _dynamicValue) public {
dynamicallySizedValue = _dynamicValue;
}
function getDynamicallySizedValue() public view returns (string) {
function getDynamicallySizedValue() public view returns (string memory) {
return dynamicallySizedValue;
}
@ -125,50 +125,50 @@ contract ContractV1 is ContractInterface, Upgradeable {
}
function verifyState(address _testTarget) public onlyOwner {
require(uint(delegateGet(_testTarget, "storageValue()")) == storageValue);
require(delegateGet(_testTarget, "storageValue()") == storageValue);
bytes memory value = delegateGetBytes(_testTarget, "dynamicallySizedValue()");
require(value.length == bytes(dynamicallySizedValue).length &&
keccak256(value) == keccak256(bytes(dynamicallySizedValue)));
require(uint(delegateGet(_testTarget, "getArrayValueLength()")) == arrayValues.length);
for (uint i = 0; i < arrayValues.length; i++) {
require(uint(delegateGet(_testTarget, "getArrayValue(uint256)", bytes32(i))) ==
require(delegateGet(_testTarget, "getArrayValue(uint256)", bytes32(i)) ==
arrayValues[i]);
}
for (i = 0; i < mappingIndices.length; i++) {
for (uint i = 0; i < mappingIndices.length; i++) {
uint256 index = mappingIndices[i];
require(uint(delegateGet(_testTarget, "getMappingValue(uint256)", bytes32(index))) ==
require(delegateGet(_testTarget, "getMappingValue(uint256)", bytes32(index)) ==
mappingValues[index]);
}
require(uint(delegateGet(_testTarget, "getStructureLength1()")) == arrayStructures.length);
for (i = 0; i < arrayStructures.length; i++) {
require(delegateGet(_testTarget, "getStructureLength1()") == arrayStructures.length);
for (uint i = 0; i < arrayStructures.length; i++) {
Structure1 memory structure1 = delegateGetStructure1(_testTarget, "arrayStructures(uint256)", bytes32(i));
require(structure1.value == arrayStructures[i].value);
require(uint(delegateGet(_testTarget, "getStructureArrayLength1(uint256)", bytes32(i))) ==
require(delegateGet(_testTarget, "getStructureArrayLength1(uint256)", bytes32(i)) ==
arrayStructures[i].arrayValues.length);
for (uint j = 0; j < arrayStructures[i].arrayValues.length; j++) {
require(uint(delegateGet(
_testTarget, "getStructureArrayValue1(uint256,uint256)", bytes32(i), bytes32(j))) ==
require(delegateGet(
_testTarget, "getStructureArrayValue1(uint256,uint256)", bytes32(i), bytes32(j)) ==
arrayStructures[i].arrayValues[j]);
}
}
require(uint(delegateGet(_testTarget, "getStructureLength2()")) == mappingStructuresLength);
for (i = 0; i < mappingStructuresLength; i++) {
require(delegateGet(_testTarget, "getStructureLength2()") == mappingStructuresLength);
for (uint i = 0; i < mappingStructuresLength; i++) {
Structure2 memory structure2 = delegateGetStructure2(_testTarget, "mappingStructures(uint256)", bytes32(i));
require(structure2.value == mappingStructures[i].value);
require(uint(delegateGet(_testTarget, "getStructureArrayLength2(uint256)", bytes32(i))) ==
require(delegateGet(_testTarget, "getStructureArrayLength2(uint256)", bytes32(i)) ==
mappingStructures[i].arrayValues.length);
for (j = 0; j < mappingStructures[i].arrayValues.length; j++) {
require(uint(delegateGet(
_testTarget, "getStructureArrayValue2(uint256,uint256)", bytes32(i), bytes32(j))) ==
for (uint j = 0; j < mappingStructures[i].arrayValues.length; j++) {
require(delegateGet(
_testTarget, "getStructureArrayValue2(uint256,uint256)", bytes32(i), bytes32(j)) ==
mappingStructures[i].arrayValues[j]);
}
}
}
function delegateGetStructure1(address _target, string _signature, bytes32 _argument)
function delegateGetStructure1(address _target, string memory _signature, bytes32 _argument)
internal returns (Structure1 memory result)
{
bytes32 memoryAddress = delegateGetData(_target, _signature, 1, _argument, 0);
@ -177,7 +177,7 @@ contract ContractV1 is ContractInterface, Upgradeable {
}
}
function delegateGetStructure2(address _target, string _signature, bytes32 _argument)
function delegateGetStructure2(address _target, string memory _signature, bytes32 _argument)
internal returns (Structure2 memory result)
{
bytes32 memoryAddress = delegateGetData(_target, _signature, 1, _argument, 0);
@ -186,7 +186,7 @@ contract ContractV1 is ContractInterface, Upgradeable {
}
}
function delegateGetBytes(address _target, string _signature)
function delegateGetBytes(address _target, string memory _signature)
internal returns (bytes memory result)
{
bytes32 memoryAddress = delegateGetData(_target, _signature, 0, 0, 0);

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "./ContractInterface.sol";
@ -50,10 +50,10 @@ contract ContractV2 is ContractInterface, Upgradeable {
return storageValue;
}
function setDynamicallySizedValue(string _dynamicValue) public {
function setDynamicallySizedValue(string memory _dynamicValue) public {
dynamicallySizedValue = _dynamicValue;
}
function getDynamicallySizedValue() public view returns (string) {
function getDynamicallySizedValue() public view returns (string memory) {
return dynamicallySizedValue;
}
@ -125,33 +125,32 @@ contract ContractV2 is ContractInterface, Upgradeable {
return mappingStructures[_index].valueToCheck;
}
function getStructure1ArrayValues(uint _index) public view returns (uint[]) {
function getStructure1ArrayValues(uint _index) public view returns (uint[] memory) {
return arrayStructures[_index].arrayValues;
}
function getStructure2ArrayValues(uint _index) public view returns (uint[]) {
function getStructure2ArrayValues(uint _index) public view returns (uint[] memory) {
return mappingStructures[_index].arrayValues;
}
function verifyState(address _testTarget) public onlyOwner {
require(uint(delegateGet(_testTarget, "storageValue()")) == storageValue);
require(delegateGet(_testTarget, "storageValue()") == storageValue);
bytes memory value = delegateGetBytes(_testTarget, "dynamicallySizedValue()");
require(value.length == bytes(dynamicallySizedValue).length &&
keccak256(value) == keccak256(bytes(dynamicallySizedValue)));
require(uint(delegateGet(_testTarget, "getArrayValueLength()")) == arrayValues.length);
require(delegateGet(_testTarget, "getArrayValueLength()") == arrayValues.length);
for (uint i = 0; i < arrayValues.length; i++) {
require(
uint(delegateGet(_testTarget, "getArrayValue(uint256)", bytes32(i))) == arrayValues[i]);
require(delegateGet(_testTarget, "getArrayValue(uint256)", bytes32(i)) == arrayValues[i]);
}
for (i = 0; i < mappingIndices.length; i++) {
for (uint i = 0; i < mappingIndices.length; i++) {
uint index = mappingIndices[i];
require(uint(delegateGet(_testTarget, "getMappingValue(uint256)", bytes32(index))) ==
require(delegateGet(_testTarget, "getMappingValue(uint256)", bytes32(index)) ==
mappingValues[index]);
}
require(uint(delegateGet(_testTarget, "getStructureLength1()")) == arrayStructures.length);
for (i = 0; i < arrayStructures.length; i++) {
for (uint i = 0; i < arrayStructures.length; i++) {
Structure1 memory structure1 = delegateGetStructure1(_testTarget, "arrayStructures(uint256)", bytes32(i));
require(structure1.value == arrayStructures[i].value);
@ -163,14 +162,14 @@ contract ContractV2 is ContractInterface, Upgradeable {
}
require(uint(delegateGet(_testTarget, "getStructureLength2()")) == mappingStructuresLength);
for (i = 0; i < mappingStructuresLength; i++) {
for (uint i = 0; i < mappingStructuresLength; i++) {
Structure2 memory structure2 = delegateGetStructure2(_testTarget, "mappingStructures(uint256)", bytes32(i));
require(structure2.value == mappingStructures[i].value);
require(structure2.valueToCheck == mappingStructures[i].valueToCheck);
values = delegateGetArray(_testTarget, "getStructure2ArrayValues(uint256)", bytes32(i));
bytes32[] memory values = delegateGetArray(_testTarget, "getStructure2ArrayValues(uint256)", bytes32(i));
require(values.length == mappingStructures[i].arrayValues.length);
for (j = 0; j < mappingStructures[i].arrayValues.length; j++) {
for (uint j = 0; j < mappingStructures[i].arrayValues.length; j++) {
require(uint(values[j]) == mappingStructures[i].arrayValues[j]);
}
}
@ -178,7 +177,7 @@ contract ContractV2 is ContractInterface, Upgradeable {
require(uint(delegateGet(_testTarget, "storageValueToCheck()")) == storageValueToCheck);
}
function delegateGetStructure1(address _target, string _signature, bytes32 _argument)
function delegateGetStructure1(address _target, string memory _signature, bytes32 _argument)
internal returns (Structure1 memory result)
{
bytes32 memoryAddress = delegateGetData(_target, _signature, 1, _argument, 0);
@ -187,7 +186,7 @@ contract ContractV2 is ContractInterface, Upgradeable {
}
}
function delegateGetStructure2(address _target, string _signature, bytes32 _argument)
function delegateGetStructure2(address _target, string memory _signature, bytes32 _argument)
internal returns (Structure2 memory result)
{
bytes32 memoryAddress = delegateGetData(_target, _signature, 1, _argument, 0);
@ -198,7 +197,7 @@ contract ContractV2 is ContractInterface, Upgradeable {
}
}
function delegateGetBytes(address _target, string _signature)
function delegateGetBytes(address _target, string memory _signature)
internal returns (bytes memory result)
{
bytes32 memoryAddress = delegateGetData(_target, _signature, 0, 0, 0);
@ -212,7 +211,7 @@ contract ContractV2 is ContractInterface, Upgradeable {
**/
function delegateGetArray(
address _target,
string _signature,
string memory _signature,
bytes32 _argument
)
public returns (bytes32[] memory result)

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.24;
pragma solidity ^0.5.3;
import "./ContractV2.sol";
@ -20,6 +20,6 @@ contract ContractV3 is ContractV2 {
function verifyState(address _testTarget) public onlyOwner {
super.verifyState(_testTarget);
require(uint(delegateGet(_testTarget, "anotherStorageValue()")) == anotherStorageValue);
require(delegateGet(_testTarget, "anotherStorageValue()") == anotherStorageValue);
}
}

View File

@ -49,9 +49,9 @@ def test_staking(testerchain, token, escrow_contract):
assert 10000 == token.functions.balanceOf(ursula2).call()
# Ursula and Ursula(2) give Escrow rights to transfer
tx = token.functions.approve(escrow.address, 1100).transact({'from': ursula1})
tx = token.functions.approve(escrow.address, 1000).transact({'from': ursula1})
testerchain.wait_for_receipt(tx)
assert 1100 == token.functions.allowance(ursula1, escrow.address).call()
assert 1000 == token.functions.allowance(ursula1, escrow.address).call()
tx = token.functions.approve(escrow.address, 500).transact({'from': ursula2})
testerchain.wait_for_receipt(tx)
assert 500 == token.functions.allowance(ursula2, escrow.address).call()

View File

@ -62,12 +62,6 @@ def test_create_token(testerchain):
testerchain.wait_for_receipt(tx)
assert 10 == token.functions.balanceOf(token.address).call()
# Can burn own tokens
tx = token.functions.burn(1).transact({'from': account2})
testerchain.wait_for_receipt(tx)
assert 9 == token.functions.balanceOf(account2).call()
assert 10 ** 9 - 1 == token.functions.totalSupply().call()
@pytest.mark.slow()
def test_approve_and_call(testerchain):
@ -104,3 +98,24 @@ def test_approve_and_call(testerchain):
assert 25 == mock.functions.value().call()
assert token.address == mock.functions.tokenContract().call()
assert 111 == testerchain.interface.w3.toInt(mock.functions.extraData().call())
# Can't approve non zero value
with pytest.raises((TransactionFailed, ValueError)):
tx = token.functions.approve(account1, 100).transact({'from': creator})
testerchain.wait_for_receipt(tx)
assert 50 == token.functions.allowance(creator, account1).call()
# Change to zero value and set new one
tx = token.functions.approve(account1, 0).transact({'from': creator})
testerchain.wait_for_receipt(tx)
assert 0 == token.functions.allowance(creator, account1).call()
tx = token.functions.approve(account1, 100).transact({'from': creator})
testerchain.wait_for_receipt(tx)
assert 100 == token.functions.allowance(creator, account1).call()
# Decrease value
tx = token.functions.decreaseAllowance(account1, 60).transact({'from': creator})
testerchain.wait_for_receipt(tx)
assert 40 == token.functions.allowance(creator, account1).call()
tx = token.functions.increaseAllowance(account1, 10).transact({'from': creator})
testerchain.wait_for_receipt(tx)
assert 50 == token.functions.allowance(creator, account1).call()