aboutsummaryrefslogtreecommitdiffstats
path: root/test/NodeStaker.js
blob: 9a72753e2af009e4ca02618d7b91cceafde19dde (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
const {balance} = require('openzeppelin-test-helpers');
const t_assert = require('truffle-assertions');
const {getTxCost} = require('./utils');

const GovernanceMock = artifacts.require('GovernanceMock');
const NodeStaker = artifacts.require('./test/NodeStakerMock');
const minStake = new web3.utils.BN(web3.utils.toWei('1', 'ether'));

contract('NodeStaker', accounts => {
  const owner = accounts[0];
  const owner2 = accounts[1];

  let govMock;
  let nodeStaker;
  let nodeStaker1;
  let nodeStaker2;

  const deploy = async () => {
    govMock = await GovernanceMock.new();
    nodeStaker = await NodeStaker.new(false);
    await nodeStaker.setGovernance(govMock.address);
    nodeStaker.sendTransaction({value: minStake});
    nodeStaker.transferOwnership(owner);
  };

  before(async () => {
    await deploy();
  });

  describe('test register', () => {
    it('can not withdraw before register', async () => {
      await t_assert.reverts(nodeStaker.withdraw(), 'not registered yet');
    });

    it('can not replace node publicKey before register', async () => {
      await t_assert.reverts(
        nodeStaker.replaceNodePublicKey('0x4321'),
        'not registered yet',
      );
    });

    it('register', async () => {
      await t_assert.passes(
        nodeStaker.register('0x1234', 'name', 'email', 'location', 'url', {
          from: owner,
        }),
      );
      const b = await balance.current(nodeStaker.address);
      assert.equal(b, 0);
    });

    it('can not register again', async () => {
      await t_assert.reverts(
        nodeStaker.register('0x1234', 'name', 'email', 'location', 'url'),
        'already registered',
      );
    });

    it('should replace node publicKey successfully', async () => {
      const tx = await nodeStaker.replaceNodePublicKey('0x4321');
      t_assert.eventEmitted(tx, 'NodePublicKeyReplaced', ev => {
        return ev.oldKey === '0x1234' && ev.newKey === '0x4321';
      });
    });
  });

  describe('test foundation only functions', async () => {
    const vestAmount = new web3.utils.BN(web3.utils.toWei('0.2', 'ether'));

    it('should transferOwnership by foundation successfully', async () => {
      const tx = await nodeStaker.transferOwnershipByFoundation(owner2);
      t_assert.eventEmitted(tx, 'OwnershipTranferedByFoundation', ev => {
        return ev.from === owner && ev.to === owner2;
      });
    });

    it('can not unstake before vest', async () => {
      t_assert.reverts(
        nodeStaker.unstakeByFoundation('1'),
        'unstaking amount should not be greater than availableUnstakeAmount.',
      );
    });

    it('should vest successfully', async () => {
      const tx = await nodeStaker.vest(vestAmount);
      t_assert.eventEmitted(tx, 'NodeVested', ev => {
        return ev.amount.toString() === vestAmount.toString();
      });
      const b = await balance.current(nodeStaker.address);
      assert.equal(b, 0);
    });

    it('can not unstake more than vested', async () => {
      t_assert.reverts(
        nodeStaker.unstakeByFoundation(minStake),
        'unstaking amount should not be greater than availableUnstakeAmount.',
      );
      const b = await balance.current(nodeStaker.address);
      assert.equal(b, 0);
    });

    it('should unstakeByFoundation successfully', async () => {
      let tx = await nodeStaker.unstakeByFoundation(vestAmount);
      t_assert.eventEmitted(tx, 'UnstakedByFoundation', ev => {
        return ev.amount.toString() === vestAmount.toString();
      });
      let b = await balance.current(nodeStaker.address);
      assert.equal(b, 0);
      const staked = await nodeStaker.getStakedAmount();
      assert.equal(staked.toString(), minStake.sub(vestAmount).toString());
      const unstacked = await nodeStaker.getUnstakedAmount();
      assert.equal(unstacked.toString(), vestAmount.toString());
      b = await balance.current(nodeStaker.address);
      assert.equal(b, 0);

      // withdraw
      let balanceBeforeWithdraw = await web3.eth.getBalance(owner2);
      balanceBeforeWithdraw = new web3.utils.BN(balanceBeforeWithdraw);
      tx = await nodeStaker.withdraw({from: owner2});
      t_assert.eventEmitted(tx, 'NodeWithdrawn', ev => {
        return ev.amount.toString() === vestAmount.toString();
      });
      let txCost = await getTxCost(tx);
      let balanceAfterWithdraw = await web3.eth.getBalance(owner2);
      balanceAfterWithdraw = new web3.utils.BN(balanceAfterWithdraw);
      assert.equal(
        balanceAfterWithdraw.toString(),
        balanceBeforeWithdraw
          .sub(txCost)
          .add(vestAmount)
          .toString(),
      );

      // withdraw again
      balanceBeforeWithdraw = await web3.eth.getBalance(owner2);
      balanceBeforeWithdraw = new web3.utils.BN(balanceBeforeWithdraw);
      tx = await nodeStaker.withdraw({from: owner2});
      t_assert.eventEmitted(tx, 'NodeWithdrawn', ev => {
        return ev.amount.toString() === '0';
      });
      txCost = await getTxCost(tx);
      balanceAfterWithdraw = await web3.eth.getBalance(owner2);
      balanceAfterWithdraw = new web3.utils.BN(balanceAfterWithdraw);
      assert.equal(
        balanceAfterWithdraw.toString(),
        balanceBeforeWithdraw.sub(txCost).toString(),
      );
    });
  });
});