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

Extra prod tests #1299

Merged
merged 6 commits into from
May 27, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 40 additions & 0 deletions test/integration/behaviors/erc20.behavior.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const ethers = require('ethers');
const { assert } = require('../../contracts/common');

function itBehavesLikeAnERC20({ ctx }) {
describe('erc20 functionality', () => {
let user;
let Synthetix;

let userBalance;

before('target contracts and users', () => {
({ Synthetix } = ctx.contracts);

user = ctx.user;
});

before('record user balance', async () => {
userBalance = await Synthetix.balanceOf(user.address);
});

describe('when the owner transfers SNX to the user', () => {
const amountToTransfer = ethers.utils.parseEther('1');

before('transfer', async () => {
Synthetix = Synthetix.connect(ctx.owner);

const tx = await Synthetix.transfer(user.address, amountToTransfer);
await tx.wait();
});

it('increases the users balance', async () => {
assert.bnEqual(await Synthetix.balanceOf(user.address), userBalance.add(amountToTransfer));
});
});
});
}

module.exports = {
itBehavesLikeAnERC20,
};
112 changes: 47 additions & 65 deletions test/integration/behaviors/exchange.behavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,96 +2,78 @@ const ethers = require('ethers');
const { assert } = require('../../contracts/common');
const { toBytes32 } = require('../../../index');
const { ensureBalance } = require('../utils/balances');
const { wait, sendDummyTx } = require('../utils/rpc');
const { ignoreMinimumStakeTime } = require('../utils/stakeTime');

function itCanPerformExchanges({ ctx }) {
const sUSDAmount = ethers.utils.parseEther('100');
function itCanExchange({ ctx }) {
describe('exchanging', () => {
const sUSDAmount = ethers.utils.parseEther('100');

let owner;
let balancesETH, balancesUSD;
let Synthetix, Exchanger, SynthsETH, SynthsUSD, SystemSettings;
let originalWaitingPeriod;
let owner;
let balancesETH, balancesUSD;
let Synthetix, Exchanger, SynthsETH, SynthsUSD;

before('target contracts and users', () => {
({ Synthetix, Exchanger, SynthsETH, SynthsUSD, SystemSettings } = ctx.contracts);
before('target contracts and users', () => {
({ Synthetix, Exchanger, SynthsETH, SynthsUSD } = ctx.contracts);

owner = ctx.owner;
});

before('ensure the owner has sUSD', async () => {
await ensureBalance({ ctx, symbol: 'sUSD', user: owner, balance: sUSDAmount });
});

before('record and reduce waiting period', async () => {
SystemSettings = SystemSettings.connect(ctx.owner);

originalWaitingPeriod = await SystemSettings.waitingPeriodSecs();

const tx = await SystemSettings.setWaitingPeriodSecs(1);
await tx.wait();
});

after('restore waiting period', async () => {
const tx = await SystemSettings.setWaitingPeriodSecs(originalWaitingPeriod);
await tx.wait();
});

describe('when the owner exchanges sUSD to sETH', () => {
before('record balances', async () => {
balancesETH = await SynthsETH.balanceOf(owner.address);
owner = ctx.owner;
});

before('perform the exchange', async () => {
Synthetix = Synthetix.connect(owner);

const tx = await Synthetix.exchange(toBytes32('sUSD'), sUSDAmount, toBytes32('sETH'));
await tx.wait();
before('ensure the owner has sUSD', async () => {
await ensureBalance({ ctx, symbol: 'sUSD', user: owner, balance: sUSDAmount });
});

it('receives the expected amount of sETH', async () => {
const [expectedAmount, ,] = await Exchanger.getAmountsForExchange(
sUSDAmount,
toBytes32('sUSD'),
toBytes32('sETH')
);

assert.bnEqual(await SynthsETH.balanceOf(owner.address), balancesETH.add(expectedAmount));
});

// TODO: Disabled until we understand more about the time granularity of the
// L2 chain on the ops tool.
describe.skip('when the owner exchanges sETH to sUSD', () => {
before('ensure the waiting period has passed', async () => {
await sendDummyTx({ ctx });
await wait({ seconds: 60 });
await sendDummyTx({ ctx });
});

describe('when the owner exchanges sUSD to sETH', () => {
before('record balances', async () => {
balancesUSD = await SynthsUSD.balanceOf(owner.address);
balancesETH = await SynthsETH.balanceOf(owner.address);
});

before('perform the exchange', async () => {
Synthetix = Synthetix.connect(owner);

const tx = await Synthetix.exchange(toBytes32('sETH'), balancesETH, toBytes32('sUSD'));
const tx = await Synthetix.exchange(toBytes32('sUSD'), sUSDAmount, toBytes32('sETH'));
await tx.wait();
});

it('receives the expected amount of sUSD', async () => {
it('receives the expected amount of sETH', async () => {
const [expectedAmount, ,] = await Exchanger.getAmountsForExchange(
balancesETH,
toBytes32('sETH'),
toBytes32('sUSD')
sUSDAmount,
toBytes32('sUSD'),
toBytes32('sETH')
);

assert.bnEqual(await SynthsUSD.balanceOf(owner.address), balancesUSD.add(expectedAmount));
assert.bnEqual(await SynthsETH.balanceOf(owner.address), balancesETH.add(expectedAmount));
});

// TODO: Disabled until we understand time granularity in the ops tool L2 chain
describe.skip('when the owner exchanges sETH to sUSD', () => {
ignoreMinimumStakeTime({ ctx });

before('record balances', async () => {
balancesUSD = await SynthsUSD.balanceOf(owner.address);
balancesETH = await SynthsETH.balanceOf(owner.address);
});

before('perform the exchange', async () => {
Synthetix = Synthetix.connect(owner);

const tx = await Synthetix.exchange(toBytes32('sETH'), balancesETH, toBytes32('sUSD'));
await tx.wait();
});

it('receives the expected amount of sUSD', async () => {
const [expectedAmount, ,] = await Exchanger.getAmountsForExchange(
balancesETH,
toBytes32('sETH'),
toBytes32('sUSD')
);

assert.bnEqual(await SynthsUSD.balanceOf(owner.address), balancesUSD.add(expectedAmount));
});
});
});
});
}

module.exports = {
itCanPerformExchanges,
itCanExchange,
};
65 changes: 65 additions & 0 deletions test/integration/behaviors/stake.behavior.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const ethers = require('ethers');
const { assert } = require('../../contracts/common');
const { ensureBalance } = require('../utils/balances');
const { ignoreMinimumStakeTime } = require('../utils/stakeTime');

function itCanMintAndBurn({ ctx }) {
describe('staking', () => {
const SNXAmount = ethers.utils.parseEther('10');
const sUSDamount = ethers.utils.parseEther('1');

let user;
let Synthetix, SynthsUSD;
let balancesUSD;

before('target contracts and users', () => {
({ Synthetix, SynthsUSD } = ctx.contracts);

user = ctx.user;
});

before('ensure the user has enough SNX', async () => {
await ensureBalance({ ctx, symbol: 'SNX', user, balance: SNXAmount });
});

describe('when the user issues sUSD', () => {
before('record balances', async () => {
balancesUSD = await SynthsUSD.balanceOf(user.address);
});

before('perform the issuance', async () => {
Synthetix = Synthetix.connect(user);

const tx = await Synthetix.issueSynths(sUSDamount);
await tx.wait();
});

it('issues the expected amount of sUSD', async () => {
assert.bnEqual(await SynthsUSD.balanceOf(user.address), balancesUSD.add(sUSDamount));
});
});

describe('when the user burns sUSD', () => {
ignoreMinimumStakeTime({ ctx });

before('record values', async () => {
balancesUSD = await SynthsUSD.balanceOf(user.address);
});

before('burn the sUSD', async () => {
Synthetix = Synthetix.connect(user);

const tx = await Synthetix.burnSynths(sUSDamount);
await tx.wait();
});

it('burnt the expected amount of sUSD', async () => {
assert.bnEqual(await SynthsUSD.balanceOf(user.address), balancesUSD.sub(sUSDamount));
});
});
});
}

module.exports = {
itCanMintAndBurn,
};
13 changes: 13 additions & 0 deletions test/integration/l1/Synthetix.l1.integration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const { bootstrapL1 } = require('../utils/bootstrap');
const { itCanExchange } = require('../behaviors/exchange.behavior');
const { itCanMintAndBurn } = require('../behaviors/stake.behavior');
const { itBehavesLikeAnERC20 } = require('../behaviors/erc20.behavior');

describe('Synthetix integration tests (L1)', () => {
const ctx = this;
bootstrapL1({ ctx });

itCanExchange({ ctx });
itCanMintAndBurn({ ctx });
itBehavesLikeAnERC20({ ctx });
});
9 changes: 0 additions & 9 deletions test/integration/l1/exchange.l1.integration.js

This file was deleted.

13 changes: 13 additions & 0 deletions test/integration/l2/Synthetix.l2.integration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const { bootstrapL2 } = require('../utils/bootstrap');
const { itCanExchange } = require('../behaviors/exchange.behavior');
const { itCanMintAndBurn } = require('../behaviors/stake.behavior');
const { itBehavesLikeAnERC20 } = require('../behaviors/erc20.behavior');

describe('Synthetix integration tests (L2)', () => {
const ctx = this;
bootstrapL2({ ctx });

itCanExchange({ ctx });
itCanMintAndBurn({ ctx });
itBehavesLikeAnERC20({ ctx });
});
9 changes: 0 additions & 9 deletions test/integration/l2/exchange.l2.integration.js

This file was deleted.

7 changes: 7 additions & 0 deletions test/integration/utils/rates.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ async function simulateExchangeRates({ ctx }) {
await tx.wait();
}

async function getExchangeRate({ ctx, symbol }) {
const { ExchangeRates } = ctx.contracts.ExchangeRates;

return ExchangeRates.rateForCurrency(toBytes32(symbol));
}

module.exports = {
simulateExchangeRates,
getExchangeRate,
};
23 changes: 23 additions & 0 deletions test/integration/utils/stakeTime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
function ignoreMinimumStakeTime({ ctx }) {
before('record and reduce minimumStakeTime', async () => {
let { SystemSettings } = ctx.contracts;
SystemSettings = SystemSettings.connect(ctx.owner);

ctx.minimumStakeTime = await SystemSettings.minimumStakeTime();

const tx = await SystemSettings.setMinimumStakeTime(0);
await tx.wait();
});

after('restore minimum stake time', async () => {
let { SystemSettings } = ctx.contracts;
SystemSettings = SystemSettings.connect(ctx.owner);

const tx = await SystemSettings.setMinimumStakeTime(ctx.minimumStakeTime);
await tx.wait();
});
}

module.exports = {
ignoreMinimumStakeTime,
};