Skip to content

Commit 4088912

Browse files
author
justin j. moses
authored
Coverage improvements (Synthetixio#508)
1 parent 91390c5 commit 4088912

File tree

5 files changed

+250
-9
lines changed

5 files changed

+250
-9
lines changed

.solcover.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const {
44

55
module.exports = {
66
port: 8545,
7-
skipFiles: ['test-helpers'],
7+
skipFiles: ['test-helpers', 'EscrowChecker.sol'],
88
providerOptions: {
99
default_balance_ether: 10000000000000, // extra zero just in case (coverage consumes more gas)
1010
time: new Date(inflationStartTimestampInSecs * 1000),

contracts/Synthetix.sol

-7
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import "./interfaces/IEtherCollateral.sol";
1515
import "./interfaces/IIssuer.sol";
1616
import "./interfaces/ISynthetixState.sol";
1717
import "./interfaces/IExchangeRates.sol";
18-
import "./interfaces/IFeePool.sol";
1918
import "./SupplySchedule.sol";
2019
import "./interfaces/IRewardEscrow.sol";
2120
import "./interfaces/IHasBalance.sol";
@@ -44,7 +43,6 @@ contract Synthetix is IERC20, ExternStateToken, MixinResolver, ISynthetix {
4443
bytes32 private constant CONTRACT_ISSUER = "Issuer";
4544
bytes32 private constant CONTRACT_SYNTHETIXSTATE = "SynthetixState";
4645
bytes32 private constant CONTRACT_EXRATES = "ExchangeRates";
47-
bytes32 private constant CONTRACT_FEEPOOL = "FeePool";
4846
bytes32 private constant CONTRACT_SUPPLYSCHEDULE = "SupplySchedule";
4947
bytes32 private constant CONTRACT_REWARDESCROW = "RewardEscrow";
5048
bytes32 private constant CONTRACT_SYNTHETIXESCROW = "SynthetixEscrow";
@@ -57,7 +55,6 @@ contract Synthetix is IERC20, ExternStateToken, MixinResolver, ISynthetix {
5755
CONTRACT_ISSUER,
5856
CONTRACT_SYNTHETIXSTATE,
5957
CONTRACT_EXRATES,
60-
CONTRACT_FEEPOOL,
6158
CONTRACT_SUPPLYSCHEDULE,
6259
CONTRACT_REWARDESCROW,
6360
CONTRACT_SYNTHETIXESCROW,
@@ -104,10 +101,6 @@ contract Synthetix is IERC20, ExternStateToken, MixinResolver, ISynthetix {
104101
return IExchangeRates(requireAndGetAddress(CONTRACT_EXRATES, "Missing ExchangeRates address"));
105102
}
106103

107-
function feePool() internal view returns (IFeePool) {
108-
return IFeePool(requireAndGetAddress(CONTRACT_FEEPOOL, "Missing FeePool address"));
109-
}
110-
111104
function supplySchedule() internal view returns (SupplySchedule) {
112105
return SupplySchedule(requireAndGetAddress(CONTRACT_SUPPLYSCHEDULE, "Missing SupplySchedule address"));
113106
}

test/contracts/MultiCollateralSynth.js

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ contract('MultiCollateralSynth', accounts => {
2020
before(async () => {
2121
({ AddressResolver: resolver, Synthetix: synthetix } = await setupAllContracts({
2222
accounts,
23+
mocks: { FeePool: true },
2324
contracts: ['AddressResolver', 'Synthetix'],
2425
}));
2526
});

test/contracts/SynthetixEscrow.js

+248
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
'use strict';
2+
3+
const { contract } = require('@nomiclabs/buidler');
4+
5+
const { assert, addSnapshotBeforeRestoreAfterEach } = require('./common');
6+
7+
const { mockToken, setupContract } = require('./setup');
8+
9+
const { currentTime, fastForward, toUnit, ZERO_ADDRESS } = require('../utils')();
10+
11+
contract('SynthetixEscrow', async accounts => {
12+
const DAY = 86400;
13+
const WEEK = 604800;
14+
const YEAR = 31556926;
15+
16+
const [, owner, , account1, account2] = accounts;
17+
let escrow, synthetix;
18+
19+
// Run once at beginning - snapshots will take care of resetting this before each test
20+
before(async () => {
21+
// Mock SNX
22+
({ token: synthetix } = await mockToken({ accounts, name: 'Synthetix', symbol: 'SNX' }));
23+
24+
escrow = await setupContract({
25+
accounts,
26+
contract: 'SynthetixEscrow',
27+
cache: {
28+
Synthetix: synthetix,
29+
},
30+
});
31+
});
32+
33+
addSnapshotBeforeRestoreAfterEach();
34+
35+
describe('Constructor & Settings ', async () => {
36+
it('should set synthetix on contructor', async () => {
37+
const synthetixAddress = await escrow.synthetix();
38+
assert.equal(synthetixAddress, synthetix.address);
39+
});
40+
41+
it('should set owner on contructor', async () => {
42+
const ownerAddress = await escrow.owner();
43+
assert.equal(ownerAddress, owner);
44+
});
45+
46+
it('should allow owner to set synthetix', async () => {
47+
await escrow.setSynthetix(ZERO_ADDRESS, { from: owner });
48+
const synthetixAddress = await escrow.synthetix();
49+
assert.equal(synthetixAddress, ZERO_ADDRESS);
50+
});
51+
});
52+
53+
describe('Functions', async () => {
54+
const getYearFromNow = async () => {
55+
const timestamp = await currentTime();
56+
return timestamp + YEAR;
57+
};
58+
59+
describe('Vesting Schedule Writes', async () => {
60+
it('should not create a vesting entry with a zero amount', async () => {
61+
// Transfer of SNX to the escrow must occur before creating an entry
62+
await synthetix.transfer(escrow.address, toUnit('1'), {
63+
from: owner,
64+
});
65+
66+
await assert.revert(
67+
escrow.appendVestingEntry(account1, await getYearFromNow(), toUnit('0'), { from: owner })
68+
);
69+
});
70+
71+
it('should not create a vesting entry if there is not enough SNX in the contracts balance', async () => {
72+
// Transfer of SNX to the escrow must occur before creating an entry
73+
await synthetix.transfer(escrow.address, toUnit('1'), {
74+
from: owner,
75+
});
76+
await assert.revert(
77+
escrow.appendVestingEntry(account1, await getYearFromNow(), toUnit('10'), { from: owner })
78+
);
79+
});
80+
});
81+
82+
describe('Vesting Schedule Reads ', async () => {
83+
beforeEach(async () => {
84+
// Transfer of SNX to the escrow must occur before creating a vestinng entry
85+
await synthetix.transfer(escrow.address, toUnit('6000'), {
86+
from: owner,
87+
});
88+
89+
// Add a few vesting entries as the feepool address
90+
await escrow.appendVestingEntry(account1, await getYearFromNow(), toUnit('1000'), {
91+
from: owner,
92+
});
93+
await fastForward(WEEK);
94+
await escrow.appendVestingEntry(account1, await getYearFromNow(), toUnit('2000'), {
95+
from: owner,
96+
});
97+
await fastForward(WEEK);
98+
await escrow.appendVestingEntry(account1, await getYearFromNow(), toUnit('3000'), {
99+
from: owner,
100+
});
101+
});
102+
103+
it('should append a vesting entry and increase the contracts balance', async () => {
104+
const balanceOfRewardEscrow = await synthetix.balanceOf(escrow.address);
105+
assert.bnEqual(balanceOfRewardEscrow, toUnit('6000'));
106+
});
107+
108+
it('should get an accounts total Vested Account Balance', async () => {
109+
const balanceOf = await escrow.balanceOf(account1);
110+
assert.bnEqual(balanceOf, toUnit('6000'));
111+
});
112+
113+
it('should get an accounts number of vesting entries', async () => {
114+
const numVestingEntries = await escrow.numVestingEntries(account1);
115+
assert.equal(numVestingEntries, 3);
116+
});
117+
118+
it('should get an accounts vesting schedule entry by index', async () => {
119+
let vestingScheduleEntry;
120+
vestingScheduleEntry = await escrow.getVestingScheduleEntry(account1, 0);
121+
assert.bnEqual(vestingScheduleEntry[1], toUnit('1000'));
122+
123+
vestingScheduleEntry = await escrow.getVestingScheduleEntry(account1, 1);
124+
assert.bnEqual(vestingScheduleEntry[1], toUnit('2000'));
125+
126+
vestingScheduleEntry = await escrow.getVestingScheduleEntry(account1, 2);
127+
assert.bnEqual(vestingScheduleEntry[1], toUnit('3000'));
128+
});
129+
130+
it('should get an accounts vesting time for a vesting entry index', async () => {
131+
const oneYearAhead = await getYearFromNow();
132+
assert.isAtLeast(oneYearAhead, parseInt(await escrow.getVestingTime(account1, 0)));
133+
assert.isAtLeast(oneYearAhead, parseInt(await escrow.getVestingTime(account1, 1)));
134+
assert.isAtLeast(oneYearAhead, parseInt(await escrow.getVestingTime(account1, 2)));
135+
});
136+
137+
it('should get an accounts vesting quantity for a vesting entry index', async () => {
138+
assert.bnEqual(await escrow.getVestingQuantity(account1, 0), toUnit('1000'));
139+
assert.bnEqual(await escrow.getVestingQuantity(account1, 1), toUnit('2000'));
140+
assert.bnEqual(await escrow.getVestingQuantity(account1, 2), toUnit('3000'));
141+
});
142+
});
143+
144+
describe('Partial Vesting', async () => {
145+
beforeEach(async () => {
146+
// Transfer of SNX to the escrow must occur before creating a vestinng entry
147+
await synthetix.transfer(escrow.address, toUnit('6000'), {
148+
from: owner,
149+
});
150+
151+
// Add a few vesting entries as the feepool address
152+
await escrow.appendVestingEntry(account1, await getYearFromNow(), toUnit('1000'), {
153+
from: owner,
154+
});
155+
await fastForward(WEEK);
156+
await escrow.appendVestingEntry(account1, await getYearFromNow(), toUnit('2000'), {
157+
from: owner,
158+
});
159+
await fastForward(WEEK);
160+
await escrow.appendVestingEntry(account1, await getYearFromNow(), toUnit('3000'), {
161+
from: owner,
162+
});
163+
164+
// fastForward to vest only the first weeks entry
165+
await fastForward(YEAR - WEEK * 2);
166+
167+
// Vest
168+
await escrow.vest({ from: account1 });
169+
});
170+
171+
it('should get an accounts next vesting entry index', async () => {
172+
assert.bnEqual(await escrow.getNextVestingIndex(account1), 1);
173+
});
174+
175+
it('should get an accounts next vesting entry', async () => {
176+
const vestingScheduleEntry = await escrow.getNextVestingEntry(account1);
177+
assert.bnEqual(vestingScheduleEntry[1], toUnit('2000'));
178+
});
179+
180+
it('should get an accounts next vesting time', async () => {
181+
const fiveDaysAhead = (await currentTime()) + DAY * 5;
182+
assert.isAtLeast(parseInt(await escrow.getNextVestingTime(account1)), fiveDaysAhead);
183+
});
184+
185+
it('should get an accounts next vesting quantity', async () => {
186+
const nextVestingQuantity = await escrow.getNextVestingQuantity(account1);
187+
assert.bnEqual(nextVestingQuantity, toUnit('2000'));
188+
});
189+
});
190+
191+
describe('Vesting', async () => {
192+
beforeEach(async () => {
193+
// Transfer of SNX to the escrow must occur before creating a vestinng entry
194+
await synthetix.transfer(escrow.address, toUnit('6000'), {
195+
from: owner,
196+
});
197+
198+
// Add a few vesting entries as the feepool address
199+
await escrow.appendVestingEntry(account1, await getYearFromNow(), toUnit('1000'), {
200+
from: owner,
201+
});
202+
await fastForward(WEEK);
203+
await escrow.appendVestingEntry(account1, await getYearFromNow(), toUnit('2000'), {
204+
from: owner,
205+
});
206+
await fastForward(WEEK);
207+
await escrow.appendVestingEntry(account1, await getYearFromNow(), toUnit('3000'), {
208+
from: owner,
209+
});
210+
211+
// Need to go into the future to vest
212+
await fastForward(YEAR + WEEK * 3);
213+
});
214+
215+
it('should vest and transfer snx from contract to the user', async () => {
216+
await escrow.vest({ from: account1 });
217+
218+
// Check user has all their vested SNX
219+
assert.bnEqual(await synthetix.balanceOf(account1), toUnit('6000'));
220+
221+
// Check escrow does not have any SNX
222+
assert.bnEqual(await synthetix.balanceOf(escrow.address), toUnit('0'));
223+
});
224+
225+
it('should vest and emit a Vest event', async () => {
226+
const vestTransaction = await escrow.vest({ from: account1 });
227+
228+
// Vested(msg.sender, now, total);
229+
const vestedEvent = vestTransaction.logs.find(log => log.event === 'Vested');
230+
assert.eventEqual(vestedEvent, 'Vested', {
231+
beneficiary: account1,
232+
value: toUnit('6000'),
233+
});
234+
});
235+
});
236+
237+
describe('Transfering', async () => {
238+
it('should not allow transfer of synthetix in escrow', async () => {
239+
// Ensure the transfer fails as all the synthetix are in escrow
240+
await assert.revert(
241+
synthetix.transfer(account2, toUnit('1000'), {
242+
from: account1,
243+
})
244+
);
245+
});
246+
});
247+
});
248+
});

test/contracts/setup.js

-1
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,6 @@ const setupAllContracts = async ({
462462
'Issuer',
463463
'Exchanger',
464464
'EtherCollateral',
465-
'FeePool',
466465
'SupplySchedule',
467466
'RewardEscrow',
468467
'SynthetixEscrow',

0 commit comments

Comments
 (0)