Skip to content
This repository has been archived by the owner on Jul 19, 2019. It is now read-only.

Commit

Permalink
deep stake testing from ZepCore
Browse files Browse the repository at this point in the history
  • Loading branch information
fiiiu committed Apr 11, 2018
1 parent 8dee272 commit 8268a86
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 79 deletions.
238 changes: 159 additions & 79 deletions test/ZepCore.test.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import assertRevert from './helpers/assertRevert';
import Deployer from '../deploy/objects/Deployer';
import RegistryManager from '../deploy/objects/RegistryManager';
import { beforeEach } from 'mocha';

const decodeLogs = require('./helpers/decodeLogs');

const BigNumber = web3.BigNumber;
const MockZepCoreV2 = artifacts.require('MockZepCoreV2');
const KernelInstance = artifacts.require('KernelInstance');
const KernelStakes = artifacts.require('KernelStakes');

const should = require('chai')
.use(require('chai-as-promised'))
.use(require('chai-bignumber')(BigNumber))
.should();

contract('ZepCore', ([_, owner, developer, user, anotherDeveloper]) => {
contract('ZepCore', ([_, owner, developer, user, anotherDeveloper, anotherUser]) => {
const newVersionCost = 2;
const developerFraction = 10;

Expand All @@ -37,89 +41,165 @@ contract('ZepCore', ([_, owner, developer, user, anotherDeveloper]) => {
await this.zepCore.register(this.kernelInstance.address, { from: developer }).should.be.fulfilled;
});

describe('staking for registered instances', async function() {
describe('staking', async function() {
const stakeValue = 42;
const unstakeValue = 24;
const transferValue = 10;

beforeEach(async function () {
await this.zepToken.transfer(developer, newVersionCost, { from: owner });
await this.zepToken.transfer(anotherDeveloper, newVersionCost, { from: owner });
await this.zepToken.approve(this.zepCore.address, newVersionCost, { from: developer });
await this.zepToken.approve(this.zepCore.address, newVersionCost, { from: anotherDeveloper });
await this.zepCore.register(this.kernelInstance.address, { from: developer });
await this.zepCore.register(this.anotherKernelInstance.address, { from: anotherDeveloper });

await this.zepToken.transfer(user, stakeValue, { from: owner });
await this.zepToken.approve(this.zepCore.address, stakeValue, { from: user });
});

it('should accept stakes', async function () {
const effectiveStake = stakeValue - Math.floor(stakeValue/developerFraction);
await this.zepCore.stake(this.kernelInstance.address, stakeValue, 0, { from: user });
const staked = await this.kernelStakes.totalStakedFor(this.kernelInstance.address);
staked.should.be.bignumber.equal(effectiveStake);
const totalStaked = await this.kernelStakes.totalStaked();
totalStaked.should.be.bignumber.equal(effectiveStake);
const tooSmallStake = developerFraction - 1;

describe('registered instances', async function() {

beforeEach(async function () {
await this.zepToken.transfer(developer, newVersionCost, { from: owner });
await this.zepToken.transfer(anotherDeveloper, newVersionCost, { from: owner });
await this.zepToken.approve(this.zepCore.address, newVersionCost, { from: developer });
await this.zepToken.approve(this.zepCore.address, newVersionCost, { from: anotherDeveloper });
await this.zepCore.register(this.kernelInstance.address, { from: developer });
await this.zepCore.register(this.anotherKernelInstance.address, { from: anotherDeveloper });

await this.zepToken.transfer(user, stakeValue, { from: owner });
await this.zepToken.approve(this.zepCore.address, stakeValue, { from: user });
});

describe('stakes', async function () {
beforeEach(async function () {
const { receipt } = await this.zepCore.stake(this.kernelInstance.address, stakeValue, 0, { from: user });
this.receipt = receipt;
this.totalStakedFor = await this.kernelStakes.totalStakedFor(this.kernelInstance.address);
})

it('should accept stakes', async function () {
const effectiveStake = stakeValue - Math.floor(stakeValue/developerFraction);
this.totalStakedFor.should.be.bignumber.equal(effectiveStake);
const totalStaked = await this.kernelStakes.totalStaked();
totalStaked.should.be.bignumber.equal(effectiveStake);
});

it('should emit a Staked event with correct amount', async function () {
this.logs = decodeLogs([this.receipt.logs[1]], KernelStakes, this.kernelStakes.address);
const total = this.logs.find(l => l.event === 'Staked').args.total;
this.totalStakedFor.should.be.bignumber.equal(total);
});

it('should reject stakes that result in no payout to dev', async function () {
await assertRevert(this.zepCore.stake(this.kernelInstance.address, tooSmallStake, 0, { from: user }));
});
});

describe('unstakes', function () {
describe('when the staker had some stake', function () {
beforeEach(async function () {
await this.zepCore.stake(this.kernelInstance.address, stakeValue, 0, { from: user });
});

describe('when the requested amount is lower than the staked amount', function () {
const effectiveStake = stakeValue - Math.floor(stakeValue/developerFraction) - unstakeValue;
beforeEach(async function () {
const { receipt } = await this.zepCore.unstake(this.kernelInstance.address, unstakeValue, 0, { from: user });
this.receipt = receipt;
})

it('unstakes the requested amount', async function () {
const staked = await this.kernelStakes.totalStakedFor(this.kernelInstance.address);
staked.should.be.bignumber.equal(effectiveStake);
const totalStaked = await this.kernelStakes.totalStaked();
totalStaked.should.be.bignumber.equal(effectiveStake);
});

it('should emit an Unstaked event with correct amount', async function () {
this.logs = decodeLogs([this.receipt.logs[0]], KernelStakes, this.kernelStakes.address);
const total = this.logs.find(l => l.event === 'Unstaked').args.total;
total.should.be.bignumber.equal(effectiveStake);
});
});

describe('when the requested amount is higher than the staked amount', function () {
it('reverts', async function () {
const tooHighUnstake = stakeValue + 1;
await assertRevert(this.zepCore.unstake(this.kernelInstance.address, tooHighUnstake, 0, { from: user}));
});
});
});

describe('when the staker had no stake', function () {
it('reverts', async function () {
await assertRevert(this.zepCore.unstake(this.kernelInstance.address, unstakeValue, 0, { from: user }));
});
});
});

describe('transfers', async function () {
it('should transfer stakes', async function () {
const effectiveStakeFirst = stakeValue - Math.floor(stakeValue/developerFraction) - transferValue;
const effectiveStakeSecond = transferValue - Math.floor(transferValue/developerFraction);
const totalEffectivelyStaked = effectiveStakeFirst + effectiveStakeSecond;

await this.zepCore.stake(this.kernelInstance.address, stakeValue, 0, { from: user });
await this.zepCore.transferStake(this.kernelInstance.address, this.anotherKernelInstance.address, transferValue, 0, { from: user });

const stakedToFirst = await this.kernelStakes.totalStakedFor(this.kernelInstance.address);
stakedToFirst.should.be.bignumber.equal(effectiveStakeFirst);

const stakedToSecond = await this.kernelStakes.totalStakedFor(this.anotherKernelInstance.address);
stakedToSecond.should.be.bignumber.equal(effectiveStakeSecond);

const totalStaked = await this.kernelStakes.totalStaked();
totalStaked.should.be.bignumber.equal(totalEffectivelyStaked);
});
});

describe('restakes', async function (){
const anotherStake = 47;
const effectiveStake = stakeValue - Math.floor(stakeValue/developerFraction) + anotherStake - Math.floor(anotherStake/developerFraction);

beforeEach(async function () {
await this.zepCore.stake(this.kernelInstance.address, stakeValue, 0, { from: user });
});

it('should accept more than one stake to the same instance by the same user', async function() {
await this.zepToken.transfer(user, anotherStake, { from: owner });
await this.zepToken.approve(this.zepCore.address, anotherStake, { from: user });
await this.zepCore.stake(this.kernelInstance.address, anotherStake, 0, { from: user });

const staked = await this.kernelStakes.totalStakedFor(this.kernelInstance.address);
staked.should.be.bignumber.equal(effectiveStake);
});

it('should accept more than one stake to the same instance by different users', async function() {
await this.zepToken.transfer(anotherUser, anotherStake, { from: owner });
await this.zepToken.approve(this.zepCore.address, anotherStake, { from: anotherUser });
await this.zepCore.stake(this.kernelInstance.address, anotherStake, 0, { from: anotherUser });

const staked = await this.kernelStakes.totalStakedFor(this.kernelInstance.address);
staked.should.be.bignumber.equal(effectiveStake);
});
});
});

it('should accept unstakes', async function () {
const effectiveStake = stakeValue - Math.floor(stakeValue/developerFraction) - unstakeValue;
await this.zepCore.stake(this.kernelInstance.address, stakeValue, 0, { from: user });
await this.zepCore.unstake(this.kernelInstance.address, unstakeValue, 0, { from: user });

const staked = await this.kernelStakes.totalStakedFor(this.kernelInstance.address);
staked.should.be.bignumber.equal(effectiveStake);
const totalStaked = await this.kernelStakes.totalStaked();
totalStaked.should.be.bignumber.equal(effectiveStake);
});

it('should transfer stakes', async function () {
const effectiveStakeFirst = stakeValue - Math.floor(stakeValue/developerFraction) - transferValue;
const effectiveStakeSecond = transferValue - Math.floor(transferValue/developerFraction);
const totalEffectivelyStaked = effectiveStakeFirst + effectiveStakeSecond;

await this.zepCore.stake(this.kernelInstance.address, stakeValue, 0, { from: user });
await this.zepCore.transferStake(this.kernelInstance.address, this.anotherKernelInstance.address, transferValue, 0, { from: user });

const stakedToFirst = await this.kernelStakes.totalStakedFor(this.kernelInstance.address);
stakedToFirst.should.be.bignumber.equal(effectiveStakeFirst);

const stakedToSecond = await this.kernelStakes.totalStakedFor(this.anotherKernelInstance.address);
stakedToSecond.should.be.bignumber.equal(effectiveStakeSecond);

const totalStaked = await this.kernelStakes.totalStaked();
totalStaked.should.be.bignumber.equal(totalEffectivelyStaked);
});
});

describe('staking for unregistered instances', async function() {
const stakeValue = 42;
const unstakeValue = 24;
const transferValue = 10;

beforeEach(async function () {
await this.zepToken.transfer(developer, newVersionCost, { from: owner });
await this.zepToken.transfer(anotherDeveloper, newVersionCost, { from: owner });
await this.zepToken.approve(this.zepCore.address, newVersionCost, { from: developer });
await this.zepToken.approve(this.zepCore.address, newVersionCost, { from: anotherDeveloper });

await this.zepToken.transfer(user, stakeValue, { from: owner });
await this.zepToken.approve(this.zepCore.address, stakeValue, { from: user });
});

it('should reject stakes', async function () {
await assertRevert(this.zepCore.stake(this.kernelInstance.address, stakeValue, 0, { from: user }));
});

it('should reject unstakes', async function () {
await assertRevert(this.zepCore.unstake(this.kernelInstance.address, unstakeValue, 0, { from: user }));
});

it('should reject stake transfers', async function () {
await this.zepCore.register(this.kernelInstance.address, { from: developer });
await this.zepCore.stake(this.kernelInstance.address, stakeValue, 0, { from: user });
await assertRevert(this.zepCore.transferStake(this.kernelInstance.address, this.anotherKernelInstance.address, transferValue, 0, { from: user }));
describe('unregistered instances', async function() {
beforeEach(async function () {
await this.zepToken.transfer(developer, newVersionCost, { from: owner });
await this.zepToken.transfer(anotherDeveloper, newVersionCost, { from: owner });
await this.zepToken.approve(this.zepCore.address, newVersionCost, { from: developer });
await this.zepToken.approve(this.zepCore.address, newVersionCost, { from: anotherDeveloper });

await this.zepToken.transfer(user, stakeValue, { from: owner });
await this.zepToken.approve(this.zepCore.address, stakeValue, { from: user });
});

it('should reject stakes', async function () {
await assertRevert(this.zepCore.stake(this.kernelInstance.address, stakeValue, 0, { from: user }));
});

it('should reject unstakes', async function () {
await assertRevert(this.zepCore.unstake(this.kernelInstance.address, unstakeValue, 0, { from: user }));
});

it('should reject stake transfers', async function () {
await this.zepCore.register(this.kernelInstance.address, { from: developer });
await this.zepCore.stake(this.kernelInstance.address, stakeValue, 0, { from: user });
await assertRevert(this.zepCore.transferStake(this.kernelInstance.address, this.anotherKernelInstance.address, transferValue, 0, { from: user }));
});
});
});

Expand Down
10 changes: 10 additions & 0 deletions test/helpers/decodeLogs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const SolidityEvent = require('web3/lib/web3/event.js');

function decodeLogs (logs, contract, address) {
return logs.map(log => {
const event = new SolidityEvent(null, contract.events[log.topics[0]], address);
return event.decode(log);
});
}

module.exports = decodeLogs

0 comments on commit 8268a86

Please sign in to comment.