Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shared: Use time helpers mock in all apps #786

Merged
merged 1 commit into from
Apr 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/finance/.solcover.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
norpc: true,
copyPackages: ['@aragon/os', '@aragon/apps-vault'],
copyPackages: ['@aragon/os', '@aragon/apps-vault', '@aragon/test-helpers'],
skipFiles: [
'test',
'@aragon/test-helpers/contracts/TimeHelpersMock.sol',
]
}
10 changes: 4 additions & 6 deletions apps/finance/contracts/test/mocks/FinanceMock.sol
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
pragma solidity 0.4.24;

import "../../Finance.sol";
import "@aragon/test-helpers/contracts/TimeHelpersMock.sol";


contract FinanceMock is Finance {
uint64 mockTime;
contract FinanceMock is Finance, TimeHelpersMock {
uint64 mockMaxPeriodTransitions = MAX_UINT64;

function getMaxUint64() public pure returns (uint64) { return MAX_UINT64; }

function mock_setMaxPeriodTransitions(uint64 i) public { mockMaxPeriodTransitions = i; }
function mock_setTimestamp(uint64 i) public { mockTime = i; }

function getMaxPeriodTransitions() internal view returns (uint64) { return mockMaxPeriodTransitions; }
function getTimestamp64() internal view returns (uint64) { return mockTime; }

function getMaxUint64() public pure returns (uint64) { return MAX_UINT64; }
}
240 changes: 115 additions & 125 deletions apps/finance/test/finance.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion apps/survey/.solcover.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
norpc: true,
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime'],
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime', '@aragon/test-helpers'],
skipFiles: [
'test',
'@aragon/test-helpers/contracts/TimeHelpersMock.sol',
]
}
3 changes: 2 additions & 1 deletion apps/survey/contracts/test/mocks/SurveyMock.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
pragma solidity 0.4.24;

import "../../Survey.sol";
import "@aragon/test-helpers/contracts/TimeHelpersMock.sol";


contract SurveyMock is Survey {
contract SurveyMock is Survey, TimeHelpersMock {
// Mint a token and create a vote in the same transaction to test snapshot block values are correct
function newTokenAndSurvey(address _holder, uint256 _tokenAmount, string _metadata, uint256 _options)
external
Expand Down
9 changes: 4 additions & 5 deletions apps/survey/test/survey.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const { assertRevert } = require('@aragon/test-helpers/assertThrow')
const getBlockNumber = require('@aragon/test-helpers/blockNumber')(web3)
const timeTravel = require('@aragon/test-helpers/timeTravel')(web3)

const getContract = name => artifacts.require(name)
const pct16 = x => new web3.BigNumber(x).times(new web3.BigNumber(10).toPower(16))
Expand Down Expand Up @@ -29,7 +28,7 @@ contract('Survey app', accounts => {
const kernelBase = await getContract('Kernel').new(true) // petrify immediately
const aclBase = await getContract('ACL').new()
daoFact = await getContract('DAOFactory').new(kernelBase.address, aclBase.address, NULL_ADDRESS)
surveyBase = await getContract('Survey').new()
surveyBase = await getContract('SurveyMock').new()

// Setup constants
ANY_ENTITY = await aclBase.ANY_ENTITY()
Expand All @@ -47,7 +46,7 @@ contract('Survey app', accounts => {
await acl.createPermission(root, dao.address, APP_MANAGER_ROLE, root, { from: root })

const receipt = await dao.newAppInstance(SURVEY_APP_ID, surveyBase.address, '0x', false, { from: root })
survey = getContract('Survey').at(receipt.logs.filter(l => l.event == 'NewAppProxy')[0].args.proxy)
survey = getContract('SurveyMock').at(receipt.logs.filter(l => l.event == 'NewAppProxy')[0].args.proxy)

await acl.createPermission(ANY_ENTITY, survey.address, CREATE_SURVEYS_ROLE, root, { from: root })
await acl.createPermission(ANY_ENTITY, survey.address, MODIFY_PARTICIPATION_ROLE, root, { from: root })
Expand Down Expand Up @@ -210,7 +209,7 @@ contract('Survey app', accounts => {
it('changing min participation doesnt affect survey min participation', async () => {
await survey.changeMinAcceptParticipationPct(pct16(50))

await timeTravel(surveyTime + 1)
await survey.mockIncreaseTime(surveyTime + 1)

const state = await survey.getSurvey(surveyId)
assert.deepEqual(state[3], minimumAcceptanceParticipationPct, 'acceptance participation in survey should stay equal')
Expand All @@ -233,7 +232,7 @@ contract('Survey app', accounts => {
})

it('throws when voting after survey closes', async () => {
await timeTravel(surveyTime + 1)
await survey.mockIncreaseTime(surveyTime + 1)
await assertRevert(async () => {
await survey.voteOption(surveyId, 1, { from: holder31 })
})
Expand Down
3 changes: 2 additions & 1 deletion apps/token-manager/.solcover.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
norpc: true,
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime'],
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime', '@aragon/test-helpers'],
skipFiles: [
'test',
'@aragon/test-helpers/contracts/TimeHelpersMock.sol',
]
}
9 changes: 3 additions & 6 deletions apps/token-manager/contracts/test/mocks/TokenManagerMock.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
pragma solidity 0.4.24;

import "../../TokenManager.sol";
import "@aragon/test-helpers/contracts/TimeHelpersMock.sol";


contract TokenManagerMock is TokenManager {
uint256 mockTime;

function mock_setTimestamp(uint256 i) public { mockTime = i; }
function getTimestamp() internal view returns (uint256) { return mockTime; }
}
/* solium-disable-next-line no-empty-blocks */
contract TokenManagerMock is TokenManager, TimeHelpersMock {}
36 changes: 20 additions & 16 deletions apps/token-manager/test/tokenmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ contract('Token Manager', accounts => {
let MINT_ROLE, ISSUE_ROLE, ASSIGN_ROLE, REVOKE_VESTINGS_ROLE, BURN_ROLE
let ETH

const NOW_TIME = 1
const NOW = 1

const root = accounts[0]
const holder = accounts[1]
Expand Down Expand Up @@ -59,7 +59,7 @@ contract('Token Manager', accounts => {

const receipt = await dao.newAppInstance('0x1234', tokenManagerBase.address, '0x', false, { from: root })
tokenManager = TokenManager.at(receipt.logs.filter(l => l.event == 'NewAppProxy')[0].args.proxy)
tokenManager.mock_setTimestamp(NOW_TIME)
tokenManager.mockSetTimestamp(NOW)

await acl.createPermission(ANY_ADDR, tokenManager.address, MINT_ROLE, root, { from: root })
await acl.createPermission(ANY_ADDR, tokenManager.address, ISSUE_ROLE, root, { from: root })
Expand Down Expand Up @@ -348,9 +348,12 @@ contract('Token Manager', accounts => {
})

context('assigning vested tokens', () => {
const startDate = NOW_TIME + 1000
const cliffDate = NOW_TIME + 2000
const vestingDate = NOW_TIME + 5000
const CLIFF_DURATION = 2000
const VESTING_DURATION = 5000

const startDate = NOW + 1000
const cliffDate = NOW + CLIFF_DURATION
const vestingDate = NOW + VESTING_DURATION

const totalTokens = 40
const revokable = true
Expand All @@ -376,22 +379,23 @@ contract('Token Manager', accounts => {
})

it('can start transferring on cliff', async () => {
await tokenManager.mock_setTimestamp(cliffDate)
await tokenManager.mockIncreaseTime(CLIFF_DURATION)

await token.transfer(holder2, 10, { from: holder })
assert.equal(await token.balanceOf(holder2), 10, 'should have received tokens')
assert.equal(await tokenManager.spendableBalanceOf(holder), 0, 'should not be able to spend more tokens')
assert.equal((await token.balanceOf(holder2)).toString(), 10, 'should have received tokens')
assert.equal((await tokenManager.spendableBalanceOf(holder)).toString(), 0, 'should not be able to spend more tokens')
})

it('can transfer all tokens after vesting', async () => {
await tokenManager.mock_setTimestamp(vestingDate)
await tokenManager.mockIncreaseTime(VESTING_DURATION)

await token.transfer(holder2, totalTokens, { from: holder })
assert.equal(await token.balanceOf(holder2), totalTokens, 'should have received tokens')
})

it('can transfer half mid vesting', async () => {
await tokenManager.mock_setTimestamp(startDate + (vestingDate - startDate) / 2)
await tokenManager.mockSetTimestamp(startDate)
await tokenManager.mockIncreaseTime((vestingDate - startDate) / 2)

await token.transfer(holder2, 20, { from: holder })

Expand All @@ -413,22 +417,22 @@ contract('Token Manager', accounts => {
})

it('cannot transfer all tokens right before vesting', async () => {
await tokenManager.mock_setTimestamp(vestingDate - 10)
await tokenManager.mockIncreaseTime(VESTING_DURATION - 10)

return assertRevert(async () => {
await token.transfer(holder2, totalTokens, { from: holder })
})
})

it('can be revoked and not vested tokens are transfered to token manager', async () => {
await tokenManager.mock_setTimestamp(cliffDate)
await tokenManager.mockIncreaseTime(CLIFF_DURATION)
await tokenManager.revokeVesting(holder, 0)

await token.transfer(holder2, 5, { from: holder })

assert.equal(await token.balanceOf(holder), 5, 'should have kept vested tokens')
assert.equal(await token.balanceOf(holder2), 5, 'should have kept vested tokens')
assert.equal(await token.balanceOf(tokenManager.address), totalTokens - 10, 'should have received unvested')
assert.equal((await token.balanceOf(holder)).toString(), 5, 'should have kept vested tokens')
assert.equal((await token.balanceOf(holder2)).toString(), 5, 'should have kept vested tokens')
assert.equal((await token.balanceOf(tokenManager.address)).toString(), totalTokens - 10, 'should have received unvested')
})

it('cannot assign a vesting to itself', async () => {
Expand Down Expand Up @@ -459,7 +463,7 @@ contract('Token Manager', accounts => {
})

// Can't create a new vesting even after other vestings have finished
await tokenManager.mock_setTimestamp(vestingDate)
await tokenManager.mockIncreaseTime(VESTING_DURATION)
await assertRevert(async () => {
await tokenManager.assignVested(holder, 1, startDate, cliffDate, vestingDate, false)
})
Expand Down
3 changes: 2 additions & 1 deletion apps/voting/.solcover.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
norpc: true,
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime'],
copyPackages: ['@aragon/os', '@aragon/apps-shared-minime', '@aragon/test-helpers'],
skipFiles: [
'test',
'@aragon/test-helpers/contracts/TimeHelpersMock.sol',
]
}
8 changes: 2 additions & 6 deletions apps/voting/contracts/test/mocks/VotingMock.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
pragma solidity 0.4.24;

import "../../Voting.sol";
import "@aragon/test-helpers/contracts/TimeHelpersMock.sol";


contract VotingMock is Voting {
uint64 mockTime;

function mock_setTimestamp(uint64 i) public { mockTime = i; }
function getTimestamp64() internal view returns (uint64) { return mockTime; }

contract VotingMock is Voting, TimeHelpersMock {
/* Ugly hack to work around this issue:
* https://github.com/trufflesuite/truffle/issues/569
* https://github.com/trufflesuite/truffle/issues/737
Expand Down
24 changes: 8 additions & 16 deletions apps/voting/test/voting.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const sha3 = require('solidity-sha3').default

const { assertRevert } = require('@aragon/test-helpers/assertThrow')
const getBlockNumber = require('@aragon/test-helpers/blockNumber')(web3)
const { encodeCallScript, EMPTY_SCRIPT } = require('@aragon/test-helpers/evmScript')
Expand Down Expand Up @@ -35,9 +33,8 @@ contract('Voting App', accounts => {
let APP_MANAGER_ROLE
let CREATE_VOTES_ROLE, MODIFY_SUPPORT_ROLE, MODIFY_QUORUM_ROLE

const startTime = 1
const NOW = 1
const votingDuration = 1000
const votingEnd = startTime + votingDuration + 1
const root = accounts[0]

before(async () => {
Expand All @@ -63,19 +60,14 @@ contract('Voting App', accounts => {

const receipt = await dao.newAppInstance('0x1234', votingBase.address, '0x', false, { from: root })
voting = Voting.at(receipt.logs.filter(l => l.event == 'NewAppProxy')[0].args.proxy)
await voting.mock_setTimestamp(startTime)
await voting.mockSetTimestamp(NOW)

await acl.createPermission(ANY_ADDR, voting.address, CREATE_VOTES_ROLE, root, { from: root })
await acl.createPermission(ANY_ADDR, voting.address, MODIFY_SUPPORT_ROLE, root, { from: root })
await acl.createPermission(ANY_ADDR, voting.address, MODIFY_QUORUM_ROLE, root, { from: root })
})

context('normal token supply, common tests', () => {
const holder20 = accounts[0]
const holder29 = accounts[1]
const holder51 = accounts[2]
const nonHolder = accounts[4]

const neededSupport = pct16(50)
const minimumAcceptanceQuorum = pct16(20)

Expand Down Expand Up @@ -252,7 +244,7 @@ contract('Voting App', accounts => {
await voting.vote(voteId, true, false, { from: holder51 })
await voting.vote(voteId, true, false, { from: holder20 })
await voting.vote(voteId, false, false, { from: holder29 })
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)

const state = await voting.getVote(voteId)
assert.equal(state[4].toString(), neededSupport.toString(), 'required support in vote should stay equal')
Expand All @@ -267,7 +259,7 @@ contract('Voting App', accounts => {
// it will succeed

await voting.vote(voteId, true, true, { from: holder29 })
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)

const state = await voting.getVote(voteId)
assert.equal(state[5].toString(), minimumAcceptanceQuorum.toString(), 'acceptance quorum in vote should stay equal')
Expand Down Expand Up @@ -310,7 +302,7 @@ contract('Voting App', accounts => {
})

it('throws when voting after voting closes', async () => {
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)
return assertRevert(async () => {
await voting.vote(voteId, true, true, { from: holder29 })
})
Expand All @@ -319,14 +311,14 @@ contract('Voting App', accounts => {
it('can execute if vote is approved with support and quorum', async () => {
await voting.vote(voteId, true, true, { from: holder29 })
await voting.vote(voteId, false, true, { from: holder20 })
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)
await voting.executeVote(voteId)
assert.equal(await executionTarget.counter(), 2, 'should have executed result')
})

it('cannot execute vote if not enough quorum met', async () => {
await voting.vote(voteId, true, true, { from: holder20 })
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)
return assertRevert(async () => {
await voting.executeVote(voteId)
})
Expand All @@ -335,7 +327,7 @@ contract('Voting App', accounts => {
it('cannot execute vote if not support met', async () => {
await voting.vote(voteId, false, true, { from: holder29 })
await voting.vote(voteId, false, true, { from: holder20 })
await voting.mock_setTimestamp(votingEnd)
await voting.mockIncreaseTime(votingDuration + 1)
return assertRevert(async () => {
await voting.executeVote(voteId)
})
Expand Down
3 changes: 2 additions & 1 deletion future-apps/payroll/.solcover.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module.exports = {
norpc: true,
copyPackages: ['@aragon/os', '@aragon/apps-finance', '@aragon/apps-vault'],
copyPackages: ['@aragon/os', '@aragon/apps-finance', '@aragon/apps-vault', '@aragon/test-helpers'],
skipFiles: [
'test',
'@aragon/test-helpers/contracts/TimeHelpersMock.sol',
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ contract('Payroll gas costs', ([owner, employee, anotherEmployee]) => {

beforeEach('initialize payroll app', async () => {
await payroll.initialize(finance.address, denominationToken.address, priceFeed.address, RATE_EXPIRATION_TIME, { from: owner })
await payroll.mockSetTimestamp(NOW)

const startDate = NOW - ONE_MONTH
const salary = annualSalaryPerSecond(100000, TOKEN_DECIMALS)
Expand Down
8 changes: 8 additions & 0 deletions shared/test-helpers/contracts/TimeHelpersMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ contract TimeHelpersMock is TimeHelpers {
else mockedTimestamp = block.timestamp.add(_seconds);
}

/**
* @dev Decreases the mocked timestamp value, used only for testing purposes
*/
function mockDecreaseTime(uint256 _seconds) public {
if (mockedTimestamp != 0) mockedTimestamp = mockedTimestamp.sub(_seconds);
else mockedTimestamp = block.timestamp.sub(_seconds);
}

/**
* @dev Advances the mocked block number value, used only for testing purposes
*/
Expand Down