Rename ValidatorSet contract to Staking contract

This commit is contained in:
Vadim 2019-03-05 08:43:21 +03:00
parent fd75ff1e45
commit 4d50918a29
10 changed files with 126 additions and 80 deletions

View File

@ -6,7 +6,7 @@ import "./ERC677BridgeToken.sol";
contract ERC677BridgeTokenRewardable is ERC677BridgeToken {
address public blockRewardContract;
address public validatorSetContract;
address public stakingContract;
constructor(
string _name,
@ -19,9 +19,9 @@ contract ERC677BridgeTokenRewardable is ERC677BridgeToken {
blockRewardContract = _blockRewardContract;
}
function setValidatorSetContract(address _validatorSetContract) onlyOwner public {
require(_validatorSetContract != address(0) && isContract(_validatorSetContract));
validatorSetContract = _validatorSetContract;
function setStakingContract(address _stakingContract) onlyOwner public {
require(_stakingContract != address(0) && isContract(_stakingContract));
stakingContract = _stakingContract;
}
modifier onlyBlockRewardContract() {
@ -29,8 +29,8 @@ contract ERC677BridgeTokenRewardable is ERC677BridgeToken {
_;
}
modifier onlyValidatorSetContract() {
require(msg.sender == validatorSetContract);
modifier onlyStakingContract() {
require(msg.sender == stakingContract);
_;
}
@ -47,29 +47,29 @@ contract ERC677BridgeTokenRewardable is ERC677BridgeToken {
}
}
function stake(address _staker, uint256 _amount) external onlyValidatorSetContract {
// Transfer `_amount` from `_staker` to `validatorSetContract`
function stake(address _staker, uint256 _amount) external onlyStakingContract {
// Transfer `_amount` from `_staker` to `stakingContract`
require(_amount <= balances[_staker]);
balances[_staker] = balances[_staker].sub(_amount);
balances[validatorSetContract] = balances[validatorSetContract].add(_amount);
emit Transfer(_staker, validatorSetContract, _amount);
balances[stakingContract] = balances[stakingContract].add(_amount);
emit Transfer(_staker, stakingContract, _amount);
}
function withdraw(address _staker, uint256 _amount) external onlyValidatorSetContract {
// Transfer `_amount` from `validatorSetContract` to `_staker`
require(_amount <= balances[validatorSetContract]);
balances[validatorSetContract] = balances[validatorSetContract].sub(_amount);
function withdraw(address _staker, uint256 _amount) external onlyStakingContract {
// Transfer `_amount` from `stakingContract` to `_staker`
require(_amount <= balances[stakingContract]);
balances[stakingContract] = balances[stakingContract].sub(_amount);
balances[_staker] = balances[_staker].add(_amount);
emit Transfer(validatorSetContract, _staker, _amount);
emit Transfer(stakingContract, _staker, _amount);
}
function transfer(address _to, uint256 _value) public returns(bool) {
require(_to != validatorSetContract);
require(_to != stakingContract);
return super.transfer(_to, _value);
}
function transferFrom(address _from, address _to, uint256 _value) public returns(bool) {
require(_to != validatorSetContract);
require(_to != stakingContract);
return super.transferFrom(_from, _to, _value);
}

View File

@ -0,0 +1,6 @@
pragma solidity 0.4.24;
contract Staking {
constructor() public {}
}

View File

@ -1,6 +0,0 @@
pragma solidity 0.4.24;
contract ValidatorSet {
constructor() {}
}

View File

@ -20,7 +20,6 @@ HOME_MIN_AMOUNT_PER_TX=500000000000000000
HOME_REQUIRED_BLOCK_CONFIRMATIONS=1
HOME_GAS_PRICE=1000000000
#for bridge erc_to_native and native_to_erc mode
BLOCK_REWARD_ADDRESS=
FOREIGN_RPC_URL=https://sokol.poa.network
@ -40,6 +39,6 @@ REQUIRED_NUMBER_OF_VALIDATORS=1
#E.g. VALIDATORS=0x 0x 0x
VALIDATORS=0x
#for bridge native_to_erc mode
#for bridge native_to_erc, erc_to_erc mode
DEPLOY_REWARDABLE_TOKEN=false
DPOS_VALIDATOR_SET_ADDRESS=
DPOS_STAKING_ADDRESS=

View File

@ -127,9 +127,9 @@ VALIDATORS=0x 0x 0x
# The flag defining whether to use ERC677BridgeTokenRewardable contract instead of
# ERC677BridgeToken.
DEPLOY_REWARDABLE_TOKEN=false
# The address of ValidatorSet contract used by ERC677BridgeTokenRewardable contract.
# The address of Staking contract used by ERC677BridgeTokenRewardable contract.
# Makes sense only when DEPLOY_REWARDABLE_TOKEN=true
DPOS_VALIDATOR_SET_ADDRESS=0x
DPOS_STAKING_ADDRESS=0x
# The address of BlockReward contract used by ERC677BridgeTokenRewardable contract.
# Makes sense only when DEPLOY_REWARDABLE_TOKEN=true
BLOCK_REWARD_ADDRESS=0x
@ -233,6 +233,16 @@ REQUIRED_NUMBER_OF_VALIDATORS=1
# the Foreign network to confirm that the finalized agreement was transferred
# correctly to the Foreign network.
VALIDATORS=0x 0x 0x
# The flag defining whether to use ERC677BridgeTokenRewardable contract instead of
# ERC677BridgeToken.
DEPLOY_REWARDABLE_TOKEN=false
# The address of Staking contract used by ERC677BridgeTokenRewardable contract.
# Makes sense only when DEPLOY_REWARDABLE_TOKEN=true
DPOS_STAKING_ADDRESS=0x
# The address of BlockReward contract used by ERC677BridgeTokenRewardable contract.
# Makes sense only when DEPLOY_REWARDABLE_TOKEN=true
BLOCK_REWARD_ADDRESS=0x
```
## `ERC-TO-NATIVE` Bridge Mode Configuration Example.

View File

@ -9,6 +9,7 @@ const EternalStorageProxy = require('../../../build/contracts/EternalStorageProx
const BridgeValidators = require('../../../build/contracts/BridgeValidators.json')
const HomeBridge = require('../../../build/contracts/HomeBridgeErcToErc.json')
const ERC677BridgeToken = require('../../../build/contracts/ERC677BridgeToken.json')
const ERC677BridgeTokenRewardable = require('../../../build/contracts/ERC677BridgeTokenRewardable.json')
const VALIDATORS = env.VALIDATORS.split(' ')
@ -27,7 +28,10 @@ const {
BRIDGEABLE_TOKEN_SYMBOL,
BRIDGEABLE_TOKEN_DECIMALS,
FOREIGN_DAILY_LIMIT,
FOREIGN_MAX_AMOUNT_PER_TX
FOREIGN_MAX_AMOUNT_PER_TX,
DEPLOY_REWARDABLE_TOKEN,
BLOCK_REWARD_ADDRESS,
DPOS_STAKING_ADDRESS
} = env
const DEPLOYMENT_ACCOUNT_ADDRESS = privateKeyToAddress(DEPLOYMENT_ACCOUNT_PRIVATE_KEY)
@ -128,7 +132,7 @@ async function deployHome() {
console.log('\n[Home] deploying Bridgeble token')
const erc677token = await deployContract(
ERC677BridgeToken,
EPLOY_REWARDABLE_TOKEN ? ERC677BridgeTokenRewardable : ERC677BridgeToken,
[BRIDGEABLE_TOKEN_NAME, BRIDGEABLE_TOKEN_SYMBOL, BRIDGEABLE_TOKEN_DECIMALS],
{ from: DEPLOYMENT_ACCOUNT_ADDRESS, network: 'home', nonce: homeNonce }
)
@ -149,6 +153,36 @@ async function deployHome() {
assert.strictEqual(Web3Utils.hexToNumber(setBridgeContract.status), 1, 'Transaction Failed')
homeNonce++
if (DEPLOY_REWARDABLE_TOKEN) {
console.log('\nset BlockReward contract on ERC677BridgeTokenRewardable')
const setBlockRewardContractData = await erc677token.methods
.setBlockRewardContract(BLOCK_REWARD_ADDRESS)
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
const setBlockRewardContract = await sendRawTxHome({
data: setBlockRewardContractData,
nonce: homeNonce,
to: erc677token.options.address,
privateKey: deploymentPrivateKey,
url: HOME_RPC_URL
})
assert.strictEqual(Web3Utils.hexToNumber(setBlockRewardContract.status), 1, 'Transaction Failed')
homeNonce++
console.log('\nset Staking contract on ERC677BridgeTokenRewardable')
const setStakingContractData = await erc677token.methods
.setStakingContract(DPOS_STAKING_ADDRESS)
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
const setStakingContract = await sendRawTxHome({
data: setStakingContractData,
nonce: homeNonce,
to: erc677token.options.address,
privateKey: deploymentPrivateKey,
url: HOME_RPC_URL
})
assert.strictEqual(Web3Utils.hexToNumber(setStakingContract.status), 1, 'Transaction Failed')
homeNonce++
}
console.log('transferring ownership of Bridgeble token to homeBridge contract')
const txOwnershipData = await erc677token.methods
.transferOwnership(homeBridgeStorage.options.address)

View File

@ -63,7 +63,7 @@ if (BRIDGE_MODE === 'NATIVE_TO_ERC') {
FOREIGN_MAX_AMOUNT_PER_TX: bigNumValidator(),
FOREIGN_MIN_AMOUNT_PER_TX: bigNumValidator(),
DEPLOY_REWARDABLE_TOKEN: envalid.bool(),
DPOS_VALIDATOR_SET_ADDRESS: addressValidator(),
DPOS_STAKING_ADDRESS: addressValidator(),
BLOCK_REWARD_ADDRESS: addressValidator()
}
}
@ -73,7 +73,10 @@ if (BRIDGE_MODE === 'ERC_TO_ERC') {
ERC20_TOKEN_ADDRESS: addressValidator(),
BRIDGEABLE_TOKEN_NAME: envalid.str(),
BRIDGEABLE_TOKEN_SYMBOL: envalid.str(),
BRIDGEABLE_TOKEN_DECIMALS: envalid.num()
BRIDGEABLE_TOKEN_DECIMALS: envalid.num(),
DEPLOY_REWARDABLE_TOKEN: envalid.bool(),
DPOS_STAKING_ADDRESS: addressValidator(),
BLOCK_REWARD_ADDRESS: addressValidator()
}
}
if (BRIDGE_MODE === 'ERC_TO_NATIVE') {

View File

@ -31,7 +31,7 @@ const {
HOME_MAX_AMOUNT_PER_TX,
DEPLOY_REWARDABLE_TOKEN,
BLOCK_REWARD_ADDRESS,
DPOS_VALIDATOR_SET_ADDRESS
DPOS_STAKING_ADDRESS
} = env
const DEPLOYMENT_ACCOUNT_ADDRESS = privateKeyToAddress(DEPLOYMENT_ACCOUNT_PRIVATE_KEY)
@ -231,18 +231,18 @@ async function deployForeign() {
assert.equal(Web3Utils.hexToNumber(setBlockRewardContract.status), 1, 'Transaction Failed')
foreignNonce++
console.log('\nset ValidatorSet contract on ERC677BridgeTokenRewardable')
const setValidatorSetContractData = await erc677bridgeToken.methods
.setValidatorSetContract(DPOS_VALIDATOR_SET_ADDRESS)
console.log('\nset Staking contract on ERC677BridgeTokenRewardable')
const setStakingContractData = await erc677bridgeToken.methods
.setStakingContract(DPOS_STAKING_ADDRESS)
.encodeABI({ from: DEPLOYMENT_ACCOUNT_ADDRESS })
const setValidatorSetContract = await sendRawTxForeign({
data: setValidatorSetContractData,
const setStakingContract = await sendRawTxForeign({
data: setStakingContractData,
nonce: foreignNonce,
to: erc677bridgeToken.options.address,
privateKey: deploymentPrivateKey,
url: FOREIGN_RPC_URL
})
assert.equal(Web3Utils.hexToNumber(setValidatorSetContract.status), 1, 'Transaction Failed')
assert.equal(Web3Utils.hexToNumber(setStakingContract.status), 1, 'Transaction Failed')
foreignNonce++
}

View File

@ -15,8 +15,8 @@ contract ERC677BridgeTokenRewardableMock is ERC677BridgeTokenRewardable {
blockRewardContract = _blockRewardContract;
}
function setValidatorSetContractMock(address _validatorSetContract) public {
validatorSetContract = _validatorSetContract;
function setStakingContractMock(address _stakingContract) public {
stakingContract = _stakingContract;
}
}

View File

@ -2,7 +2,7 @@ const POA20 = artifacts.require("ERC677BridgeToken.sol");
const POA20RewardableMock = artifacts.require("./mockContracts/ERC677BridgeTokenRewardableMock");
const ERC677ReceiverTest = artifacts.require("ERC677ReceiverTest.sol")
const BlockRewardTest = artifacts.require("BlockReward.sol")
const ValidatorSetTest = artifacts.require("ValidatorSet.sol")
const StakingTest = artifacts.require("Staking.sol")
const { ERROR_MSG, ZERO_ADDRESS} = require('./setup');
const Web3Utils = require('web3-utils');
const HomeErcToErcBridge = artifacts.require("HomeBridgeErcToErc.sol");
@ -114,36 +114,36 @@ async function testERC677BridgeToken(accounts, rewardable) {
})
})
describe('#validatorSetContract', async() => {
it('can set ValidatorSet contract', async () => {
const validatorSetContract = await ValidatorSetTest.new();
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
describe('#stakingContract', async() => {
it('can set Staking contract', async () => {
const stakingContract = await StakingTest.new();
(await token.stakingContract()).should.be.equal(ZERO_ADDRESS);
await token.setValidatorSetContract(validatorSetContract.address).should.be.fulfilled;
await token.setStakingContract(stakingContract.address).should.be.fulfilled;
(await token.validatorSetContract()).should.be.equal(validatorSetContract.address);
(await token.stakingContract()).should.be.equal(stakingContract.address);
})
it('only owner can set ValidatorSet contract', async () => {
const validatorSetContract = await ValidatorSetTest.new();
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
it('only owner can set Staking contract', async () => {
const stakingContract = await StakingTest.new();
(await token.stakingContract()).should.be.equal(ZERO_ADDRESS);
await token.setValidatorSetContract(validatorSetContract.address, {from: user }).should.be.rejectedWith(ERROR_MSG);
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
await token.setStakingContract(stakingContract.address, {from: user }).should.be.rejectedWith(ERROR_MSG);
(await token.stakingContract()).should.be.equal(ZERO_ADDRESS);
await token.setValidatorSetContract(validatorSetContract.address, {from: owner }).should.be.fulfilled;
(await token.validatorSetContract()).should.be.equal(validatorSetContract.address);
await token.setStakingContract(stakingContract.address, {from: owner }).should.be.fulfilled;
(await token.stakingContract()).should.be.equal(stakingContract.address);
})
it('fail to set invalid ValidatorSet contract address', async () => {
it('fail to set invalid Staking contract address', async () => {
const invalidContractAddress = '0xaaB52d66283F7A1D5978bcFcB55721ACB467384b';
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
(await token.stakingContract()).should.be.equal(ZERO_ADDRESS);
await token.setValidatorSetContract(invalidContractAddress).should.be.rejectedWith(ERROR_MSG);
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
await token.setStakingContract(invalidContractAddress).should.be.rejectedWith(ERROR_MSG);
(await token.stakingContract()).should.be.equal(ZERO_ADDRESS);
await token.setValidatorSetContract(ZERO_ADDRESS).should.be.rejectedWith(ERROR_MSG);
(await token.validatorSetContract()).should.be.equal(ZERO_ADDRESS);
await token.setStakingContract(ZERO_ADDRESS).should.be.rejectedWith(ERROR_MSG);
(await token.stakingContract()).should.be.equal(ZERO_ADDRESS);
})
})
@ -174,10 +174,10 @@ async function testERC677BridgeToken(accounts, rewardable) {
})
describe('#stake', async() => {
it('can only be called by ValidatorSet contract', async () => {
it('can only be called by Staking contract', async () => {
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
await token.mintReward([user], [100], {from: accounts[2] }).should.be.fulfilled;
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
await token.setStakingContractMock(accounts[3]).should.be.fulfilled;
await token.stake(user, 100, {from: accounts[4] }).should.be.rejectedWith(ERROR_MSG);
await token.stake(user, 100, {from: accounts[3] }).should.be.fulfilled;
})
@ -185,15 +185,15 @@ async function testERC677BridgeToken(accounts, rewardable) {
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
await token.mintReward([user], [99], {from: accounts[2] }).should.be.fulfilled;
(await token.balanceOf(user)).should.be.bignumber.equal(99);
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
await token.setStakingContractMock(accounts[3]).should.be.fulfilled;
await token.stake(user, 100, {from: accounts[3] }).should.be.rejectedWith(ERROR_MSG);
})
it('should decrease user\'s balance and increase ValidatorSet\'s balance', async () => {
it('should decrease user\'s balance and increase Staking\'s balance', async () => {
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
await token.mintReward([user], [100], {from: accounts[2] }).should.be.fulfilled;
(await token.balanceOf(user)).should.be.bignumber.equal(100);
(await token.balanceOf(accounts[3])).should.be.bignumber.equal(0);
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
await token.setStakingContractMock(accounts[3]).should.be.fulfilled;
await token.stake(user, 100, {from: accounts[3] }).should.be.fulfilled;
(await token.balanceOf(user)).should.be.bignumber.equal(0);
(await token.balanceOf(accounts[3])).should.be.bignumber.equal(100);
@ -201,29 +201,29 @@ async function testERC677BridgeToken(accounts, rewardable) {
})
describe('#withdraw', async() => {
it('can only be called by ValidatorSet contract', async () => {
it('can only be called by Staking contract', async () => {
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
await token.mintReward([user], [100], {from: accounts[2] }).should.be.fulfilled;
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
await token.setStakingContractMock(accounts[3]).should.be.fulfilled;
await token.stake(user, 100, {from: accounts[3] }).should.be.fulfilled;
await token.withdraw(user, 100, {from: accounts[4] }).should.be.rejectedWith(ERROR_MSG);
await token.withdraw(user, 100, {from: accounts[3] }).should.be.fulfilled;
})
it('should revert if ValidatorSet doesn\'t have enough balance', async () => {
it('should revert if Staking doesn\'t have enough balance', async () => {
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
await token.mintReward([user], [100], {from: accounts[2] }).should.be.fulfilled;
(await token.balanceOf(user)).should.be.bignumber.equal(100);
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
await token.setStakingContractMock(accounts[3]).should.be.fulfilled;
await token.stake(user, 100, {from: accounts[3] }).should.be.fulfilled;
await token.withdraw(user, 101, {from: accounts[3] }).should.be.rejectedWith(ERROR_MSG);
await token.withdraw(user, 100, {from: accounts[3] }).should.be.fulfilled;
})
it('should decrease ValidatorSet\'s balance and increase user\'s balance', async () => {
it('should decrease Staking\'s balance and increase user\'s balance', async () => {
await token.setBlockRewardContractMock(accounts[2]).should.be.fulfilled;
await token.mintReward([user], [100], {from: accounts[2] }).should.be.fulfilled;
(await token.balanceOf(user)).should.be.bignumber.equal(100);
(await token.balanceOf(accounts[3])).should.be.bignumber.equal(0);
await token.setValidatorSetContractMock(accounts[3]).should.be.fulfilled;
await token.setStakingContractMock(accounts[3]).should.be.fulfilled;
await token.stake(user, 100, {from: accounts[3] }).should.be.fulfilled;
(await token.balanceOf(user)).should.be.bignumber.equal(0);
(await token.balanceOf(accounts[3])).should.be.bignumber.equal(100);
@ -332,13 +332,13 @@ async function testERC677BridgeToken(accounts, rewardable) {
})
if (rewardable) {
it('fail to send tokens to ValidatorSet contract directly', async () => {
it('fail to send tokens to Staking contract directly', async () => {
const amount = web3.toWei(1, "ether");
const validatorSetContractAddress = accounts[2];
const stakingContractAddress = accounts[2];
const arbitraryAccountAddress = accounts[3];
await token.setValidatorSetContractMock(validatorSetContractAddress, {from: owner}).should.be.fulfilled;
await token.setStakingContractMock(stakingContractAddress, {from: owner}).should.be.fulfilled;
await token.mint(user, amount, {from: owner}).should.be.fulfilled;
await token.transfer(validatorSetContractAddress, amount, {from: user}).should.be.rejectedWith(ERROR_MSG);
await token.transfer(stakingContractAddress, amount, {from: user}).should.be.rejectedWith(ERROR_MSG);
await token.transfer(arbitraryAccountAddress, amount, {from: user}).should.be.fulfilled;
});
}
@ -346,15 +346,15 @@ async function testERC677BridgeToken(accounts, rewardable) {
if (rewardable) {
describe('#transferFrom', async() => {
it('fail to send tokens to ValidatorSet contract directly', async () => {
it('fail to send tokens to Staking contract directly', async () => {
const amount = web3.toWei(1, "ether");
const user2 = accounts[2];
const validatorSetContractAddress = accounts[3];
const stakingContractAddress = accounts[3];
const arbitraryAccountAddress = accounts[4];
await token.setValidatorSetContractMock(validatorSetContractAddress, {from: owner}).should.be.fulfilled;
await token.setStakingContractMock(stakingContractAddress, {from: owner}).should.be.fulfilled;
await token.mint(user, amount, {from: owner}).should.be.fulfilled;
await token.approve(user2, amount, {from: user}).should.be.fulfilled;
await token.transferFrom(user, validatorSetContractAddress, amount, {from: user2}).should.be.rejectedWith(ERROR_MSG);
await token.transferFrom(user, stakingContractAddress, amount, {from: user2}).should.be.rejectedWith(ERROR_MSG);
await token.transferFrom(user, arbitraryAccountAddress, amount, {from: user2}).should.be.fulfilled;
});
});