@bancor/contracts-solidity
Advanced tools
Comparing version 0.6.22 to 0.6.23
@@ -0,1 +1,9 @@ | ||
### 0.6.23 | ||
LiquidityProtection | ||
* Improved accuracy of the return/fee calculations | ||
General | ||
* Many other minor changes and cleanups | ||
### 0.6.22 | ||
@@ -2,0 +10,0 @@ LiquidityProtection |
{ | ||
"name": "@bancor/contracts-solidity", | ||
"version": "0.6.22", | ||
"version": "0.6.23", | ||
"description": "The solidity version of the Bancor smart contracts is composed of many different components that work together to create the Bancor Network deployment.", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -7,2 +7,4 @@ const { expect } = require('chai'); | ||
const LiquidTokenConverterFactory = artifacts.require('LiquidTokenConverterFactory'); | ||
const LiquidityPoolV1ConverterFactory = artifacts.require('LiquidityPoolV1ConverterFactory'); | ||
const LiquidityPoolV2ConverterFactory = artifacts.require('LiquidityPoolV2ConverterFactory'); | ||
const TypedConverterAnchorFactory = artifacts.require('TestTypedConverterAnchorFactory'); | ||
@@ -22,99 +24,103 @@ const ConverterBase = artifacts.require('ConverterBase'); | ||
before(async () => { | ||
// The following contracts are unaffected by the underlying tests, this can be shared. | ||
contractRegistry = await ContractRegistry.new(); | ||
}); | ||
for (const Factory of [LiquidTokenConverterFactory, LiquidityPoolV1ConverterFactory, LiquidityPoolV2ConverterFactory]) { | ||
describe(Factory.contractName, () => { | ||
before(async () => { | ||
// The following contracts are unaffected by the underlying tests, this can be shared. | ||
contractRegistry = await ContractRegistry.new(); | ||
}); | ||
beforeEach(async () => { | ||
converterFactory = await ConverterFactory.new(); | ||
anchorFactory = await TypedConverterAnchorFactory.new('TypedAnchor'); | ||
factory = await LiquidTokenConverterFactory.new(); | ||
}); | ||
beforeEach(async () => { | ||
converterFactory = await ConverterFactory.new(); | ||
anchorFactory = await TypedConverterAnchorFactory.new('TypedAnchor'); | ||
factory = await Factory.new(); | ||
}); | ||
it('should allow the owner to register a typed converter anchor factory', async () => { | ||
await converterFactory.registerTypedConverterAnchorFactory(anchorFactory.address); | ||
expect(await converterFactory.anchorFactories.call(await anchorFactory.converterType.call())).to.eql(anchorFactory.address); | ||
}); | ||
it('should allow the owner to register a typed converter anchor factory', async () => { | ||
await converterFactory.registerTypedConverterAnchorFactory(anchorFactory.address); | ||
expect(await converterFactory.anchorFactories.call(await anchorFactory.converterType.call())).to.eql(anchorFactory.address); | ||
}); | ||
it('should allow the owner to reregister a typed converter anchor factory', async () => { | ||
await converterFactory.registerTypedConverterAnchorFactory(anchorFactory.address); | ||
it('should allow the owner to reregister a typed converter anchor factory', async () => { | ||
await converterFactory.registerTypedConverterAnchorFactory(anchorFactory.address); | ||
const anchorFactory2 = await TypedConverterAnchorFactory.new('TypedAnchor2'); | ||
expect(await anchorFactory.converterType.call()).to.be.bignumber.equal(await anchorFactory.converterType.call()); | ||
const anchorFactory2 = await TypedConverterAnchorFactory.new('TypedAnchor2'); | ||
expect(await anchorFactory.converterType.call()).to.be.bignumber.equal(await anchorFactory.converterType.call()); | ||
await converterFactory.registerTypedConverterAnchorFactory(anchorFactory2.address); | ||
expect(await converterFactory.anchorFactories.call(await anchorFactory2.converterType.call())).to.eql(anchorFactory2.address); | ||
}); | ||
await converterFactory.registerTypedConverterAnchorFactory(anchorFactory2.address); | ||
expect(await converterFactory.anchorFactories.call(await anchorFactory2.converterType.call())).to.eql(anchorFactory2.address); | ||
}); | ||
it('should revert if a non-owner attempts to register a typed converter anchor factory', async () => { | ||
await expectRevert(converterFactory.registerTypedConverterAnchorFactory(anchorFactory.address, { from: nonOwner }), 'ERR_ACCESS_DENIED'); | ||
}); | ||
it('should revert if a non-owner attempts to register a typed converter anchor factory', async () => { | ||
await expectRevert(converterFactory.registerTypedConverterAnchorFactory(anchorFactory.address, { from: nonOwner }), 'ERR_ACCESS_DENIED'); | ||
}); | ||
it('should allow the owner to register a typed converter factory', async () => { | ||
await converterFactory.registerTypedConverterFactory(factory.address); | ||
expect(await converterFactory.converterFactories.call(await factory.converterType.call())).to.eql(factory.address); | ||
}); | ||
it('should allow the owner to register a typed converter factory', async () => { | ||
await converterFactory.registerTypedConverterFactory(factory.address); | ||
expect(await converterFactory.converterFactories.call(await factory.converterType.call())).to.eql(factory.address); | ||
}); | ||
it('should allow the owner to reregister a typed converter factory', async () => { | ||
await converterFactory.registerTypedConverterFactory(factory.address); | ||
it('should allow the owner to reregister a typed converter factory', async () => { | ||
await converterFactory.registerTypedConverterFactory(factory.address); | ||
const factory2 = await LiquidTokenConverterFactory.new(); | ||
expect(await factory.converterType.call()).to.be.bignumber.equal(await factory2.converterType.call()); | ||
const factory2 = await Factory.new(); | ||
expect(await factory.converterType.call()).to.be.bignumber.equal(await factory2.converterType.call()); | ||
await converterFactory.registerTypedConverterFactory(factory2.address); | ||
expect(await converterFactory.converterFactories.call(await factory2.converterType.call())).to.eql(factory2.address); | ||
}); | ||
await converterFactory.registerTypedConverterFactory(factory2.address); | ||
expect(await converterFactory.converterFactories.call(await factory2.converterType.call())).to.eql(factory2.address); | ||
}); | ||
it('should revert if a non-owner attempts to register a typed converter factory', async () => { | ||
await expectRevert(converterFactory.registerTypedConverterFactory(factory.address, { from: nonOwner }), 'ERR_ACCESS_DENIED'); | ||
}); | ||
it('should revert if a non-owner attempts to register a typed converter factory', async () => { | ||
await expectRevert(converterFactory.registerTypedConverterFactory(factory.address, { from: nonOwner }), 'ERR_ACCESS_DENIED'); | ||
}); | ||
it('should create an achor using an existing factory', async () => { | ||
await converterFactory.registerTypedConverterAnchorFactory(anchorFactory.address); | ||
it('should create an achor using an existing factory', async () => { | ||
await converterFactory.registerTypedConverterAnchorFactory(anchorFactory.address); | ||
const name = 'Anchor1'; | ||
await converterFactory.createAnchor(await anchorFactory.converterType.call(), name, 'ANCHOR1', 2); | ||
const name = 'Anchor1'; | ||
await converterFactory.createAnchor(await anchorFactory.converterType.call(), name, 'ANCHOR1', 2); | ||
const anchorAddress = await converterFactory.createdAnchor.call(); | ||
const anchor = await DSToken.at(anchorAddress); | ||
const anchorAddress = await converterFactory.createdAnchor.call(); | ||
const anchor = await DSToken.at(anchorAddress); | ||
expect(await anchor.name.call()).to.not.be.eql(name); | ||
expect(await anchor.name.call()).to.be.eql(await anchorFactory.name.call()); | ||
expect(await anchor.owner.call()).to.be.eql(converterFactory.address); | ||
expect(await anchor.newOwner.call()).to.be.eql(owner); | ||
}); | ||
expect(await anchor.name.call()).to.not.be.eql(name); | ||
expect(await anchor.name.call()).to.be.eql(await anchorFactory.name.call()); | ||
expect(await anchor.owner.call()).to.be.eql(converterFactory.address); | ||
expect(await anchor.newOwner.call()).to.be.eql(owner); | ||
}); | ||
it('should create an achor using custom settings', async () => { | ||
const name = 'Anchor1'; | ||
await converterFactory.createAnchor(11, name, 'ANCHOR1', 2); | ||
it('should create an achor using custom settings', async () => { | ||
const name = 'Anchor1'; | ||
await converterFactory.createAnchor(11, name, 'ANCHOR1', 2); | ||
const anchorAddress = await converterFactory.createdAnchor.call(); | ||
const anchor = await DSToken.at(anchorAddress); | ||
const anchorAddress = await converterFactory.createdAnchor.call(); | ||
const anchor = await DSToken.at(anchorAddress); | ||
expect(await anchor.name.call()).to.be.eql(name); | ||
expect(await anchor.name.call()).not.to.be.eql(await anchorFactory.name.call()); | ||
expect(await anchor.owner.call()).to.be.eql(converterFactory.address); | ||
expect(await anchor.newOwner.call()).to.be.eql(owner); | ||
}); | ||
expect(await anchor.name.call()).to.be.eql(name); | ||
expect(await anchor.name.call()).not.to.be.eql(await anchorFactory.name.call()); | ||
expect(await anchor.owner.call()).to.be.eql(converterFactory.address); | ||
expect(await anchor.newOwner.call()).to.be.eql(owner); | ||
}); | ||
it('should create converter', async () => { | ||
await converterFactory.registerTypedConverterFactory(factory.address); | ||
it('should create converter', async () => { | ||
await converterFactory.registerTypedConverterFactory(factory.address); | ||
const anchor = await DSToken.new('Token1', 'TKN1', 2); | ||
const anchor = await DSToken.new('Token1', 'TKN1', 2); | ||
const converterType = await factory.converterType.call(); | ||
const converterType = await factory.converterType.call(); | ||
const res = await converterFactory.createConverter(converterType, anchor.address, | ||
contractRegistry.address, MAX_CONVERSION_FEE); | ||
const converterAddress = await converterFactory.createdConverter.call(); | ||
const converter = await ConverterBase.at(converterAddress); | ||
const res = await converterFactory.createConverter(converterType, anchor.address, | ||
contractRegistry.address, MAX_CONVERSION_FEE); | ||
const converterAddress = await converterFactory.createdConverter.call(); | ||
const converter = await ConverterBase.at(converterAddress); | ||
expect(await converter.anchor.call()).to.be.eql(anchor.address); | ||
expect(await converter.registry.call()).to.be.eql(contractRegistry.address); | ||
expect(await converter.maxConversionFee.call()).to.be.bignumber.equal(MAX_CONVERSION_FEE); | ||
expect(await converter.owner.call()).to.be.eql(converterFactory.address); | ||
expect(await converter.newOwner.call()).to.be.eql(owner); | ||
expect(await converter.anchor.call()).to.be.eql(anchor.address); | ||
expect(await converter.registry.call()).to.be.eql(contractRegistry.address); | ||
expect(await converter.maxConversionFee.call()).to.be.bignumber.equal(MAX_CONVERSION_FEE); | ||
expect(await converter.owner.call()).to.be.eql(converterFactory.address); | ||
expect(await converter.newOwner.call()).to.be.eql(owner); | ||
expectEvent(res, 'NewConverter', { _type: converterType, _converter: converter.address, _owner: owner }); | ||
}); | ||
expectEvent(res, 'NewConverter', { _type: converterType, _converter: converter.address, _owner: owner }); | ||
}); | ||
}); | ||
} | ||
}); |
const { expect } = require('chai'); | ||
const { expectRevert, BN, balance } = require('@openzeppelin/test-helpers'); | ||
const { expectRevert, BN, balance, constants } = require('@openzeppelin/test-helpers'); | ||
const Decimal = require('decimal.js'); | ||
const { ETH_RESERVE_ADDRESS, registry } = require('./helpers/Constants'); | ||
const { MAX_UINT256 } = constants; | ||
@@ -23,3 +24,3 @@ const LiquidityPoolV1Converter = artifacts.require('LiquidityPoolV1Converter'); | ||
else { | ||
const erc20Token = await ERC20Token.new('name', 'symbol', 0, -1); | ||
const erc20Token = await ERC20Token.new('name', 'symbol', 0, MAX_UINT256); | ||
await converter.addReserve(erc20Token.address, weights[i] * 10000); | ||
@@ -86,3 +87,3 @@ } | ||
await Promise.all(reserveTokens.map((reserveToken, i) => approve(reserveToken, converter, reserveAmounts[i]))); | ||
await expectRevert(converter.addLiquidity(reserveTokens, reserveAmounts, -1), 'ERR_RETURN_TOO_LOW'); | ||
await expectRevert(converter.addLiquidity(reserveTokens, reserveAmounts, MAX_UINT256), 'ERR_RETURN_TOO_LOW'); | ||
}); | ||
@@ -89,0 +90,0 @@ |
@@ -22,3 +22,3 @@ const { expect } = require('chai'); | ||
const ConverterRegistryData = artifacts.require('ConverterRegistryData'); | ||
const TestConverterRegistry = artifacts.require('TestConverterRegistry'); | ||
const ConverterRegistry = artifacts.require('TestConverterRegistry'); | ||
const ConverterHelper = require('./helpers/Converter'); | ||
@@ -47,3 +47,3 @@ | ||
converterRegistry = await TestConverterRegistry.new(contractRegistry.address); | ||
converterRegistry = await ConverterRegistry.new(contractRegistry.address); | ||
converterRegistryData = await ConverterRegistryData.new(contractRegistry.address); | ||
@@ -663,2 +663,8 @@ | ||
.to.eql(anchors[5]); | ||
expect(await converterRegistry.getLiquidityPoolByConfig.call(2, [ETH_RESERVE_ADDRESS, erc20Token1.address], [0x4000, 0x4100])) | ||
.to.eql(anchors[6]); | ||
expect(await converterRegistry.getLiquidityPoolByConfig.call(2, [erc20Token1.address, erc20Token2.address], [0x5100, 0x5200])) | ||
.to.eql(anchors[7]); | ||
expect(await converterRegistry.getLiquidityPoolByConfig.call(2, [erc20Token2.address, ETH_RESERVE_ADDRESS], [0x6200, 0x6000])) | ||
.to.eql(anchors[8]); | ||
}); | ||
@@ -698,2 +704,8 @@ | ||
.to.eql(ZERO_ADDRESS); | ||
expect(await converterRegistry.getLiquidityPoolByConfig.call(2, [ETH_RESERVE_ADDRESS, erc20Token1.address], [0x4000, 0x4100])) | ||
.to.eql(ZERO_ADDRESS); | ||
expect(await converterRegistry.getLiquidityPoolByConfig.call(2, [erc20Token1.address, erc20Token2.address], [0x5100, 0x5200])) | ||
.to.eql(ZERO_ADDRESS); | ||
expect(await converterRegistry.getLiquidityPoolByConfig.call(2, [erc20Token2.address, ETH_RESERVE_ADDRESS], [0x6200, 0x6000])) | ||
.to.eql(ZERO_ADDRESS); | ||
}); | ||
@@ -700,0 +712,0 @@ }); |
@@ -306,8 +306,18 @@ const { expect } = require('chai'); | ||
const initFuncs = [ | ||
initWithoutReserves, | ||
initWith1Reserve, | ||
initWith2Reserves, | ||
initLPV2, | ||
initWithEtherReserve, | ||
initWithETHReserve | ||
]; | ||
const f = (a, b) => [].concat(...a.map(d => b.map(e => [].concat(d, e)))); | ||
const cartesian = (a, b, ...c) => (b ? cartesian(f(a, b), ...c) : a); | ||
const product = cartesian([initWithoutReserves, initWith1Reserve, initWith2Reserves, initLPV2, initWithEtherReserve, initWithETHReserve], | ||
[...VERSIONS, null], [false, true]); | ||
const combinations = product.filter(([init, version, active]) => !(init === initWithoutReserves && active) && | ||
!(init === initWithETHReserve && version)); | ||
const product = cartesian(initFuncs, [...VERSIONS, null], [false, true]); | ||
const combinations = product.filter(([init, version, active]) => | ||
!(init === initWithoutReserves && active) && | ||
!(init === initWithETHReserve && version) | ||
); | ||
@@ -320,15 +330,16 @@ for (const [init, version, activate] of combinations) { | ||
if (init === initWithEtherReserve) { | ||
switch (init) { | ||
case initWithEtherReserve: | ||
reserveTokens = [etherToken.address, reserveToken2.address]; | ||
// An EtherToken reserve is always upgraded to ETH_RESERVE_ADDRESS. | ||
upgradedReserveTokens = [ETH_RESERVE_ADDRESS, reserveToken2.address]; | ||
} | ||
else if (init === initWithETHReserve) { | ||
break; | ||
case initWithETHReserve: | ||
reserveTokens = [reserveToken1.address, ETH_RESERVE_ADDRESS]; | ||
upgradedReserveTokens = reserveTokens; | ||
} | ||
else { | ||
break; | ||
default: | ||
reserveTokens = [reserveToken1.address, reserveToken2.address]; | ||
upgradedReserveTokens = reserveTokens; | ||
break; | ||
} | ||
@@ -335,0 +346,0 @@ |
@@ -99,27 +99,2 @@ const { expect } = require('chai'); | ||
}); | ||
it('verifies the balances after a transfer', async () => { | ||
const value = new BN(5666); | ||
await token.issue(owner, value); | ||
const value2 = new BN(666); | ||
await token.transfer(receiver, value2); | ||
const ownerBalance = await token.balanceOf.call(owner); | ||
expect(ownerBalance).to.be.bignumber.equal(value.sub(value2)); | ||
const receiverBalance = await token.balanceOf.call(receiver); | ||
expect(receiverBalance).to.be.bignumber.equal(value2); | ||
}); | ||
it('verifies the allowance after an approval', async () => { | ||
const value = new BN(1000); | ||
await token.issue(owner, value); | ||
const value2 = new BN(200); | ||
await token.approve(receiver, value2); | ||
const allowance = await token.allowance.call(owner, receiver); | ||
expect(allowance).to.be.bignumber.equal(value2); | ||
}); | ||
}); |
module.exports = { | ||
floorSqrt, | ||
ceilSqrt, | ||
reducedRatio, | ||
@@ -18,2 +19,6 @@ normalizedRatio, | ||
function ceilSqrt(n) { | ||
return Decimal(n.toString()).sqrt().ceil().toFixed(); | ||
} | ||
function reducedRatio(a, b, max) { | ||
@@ -20,0 +25,0 @@ [a, b, max] = [...arguments].map(x => Decimal(x)); |
@@ -729,6 +729,11 @@ const { expect } = require('chai'); | ||
const getPrevAverageRateUpdateTime = async () => { | ||
const prevAverageRateUpdateTime = await converter.prevAverageRateUpdateTime.call(); | ||
return prevAverageRateUpdateTime; | ||
}; | ||
it('should be initially equal to the current rate', async () => { | ||
const averageRate = await getAverageRate(ETH_RESERVE_ADDRESS); | ||
const currentRate = await getCurrentRate(ETH_RESERVE_ADDRESS, reserveToken2.address); | ||
const prevAverageRateUpdateTime = await converter.prevAverageRateUpdateTime.call(); | ||
const prevAverageRateUpdateTime = await getPrevAverageRateUpdateTime(); | ||
@@ -745,3 +750,3 @@ expect(averageRate.n).to.be.bignumber.equal(currentRate.n); | ||
const prevAverageRate = await getAverageRate(ETH_RESERVE_ADDRESS); | ||
const prevAverageRateUpdateTime = await converter.prevAverageRateUpdateTime.call(); | ||
const prevAverageRateUpdateTime = await getPrevAverageRateUpdateTime(); | ||
@@ -752,3 +757,3 @@ await converter.setTime(now.add(duration.seconds(10))); | ||
const averageRate = await getAverageRate(ETH_RESERVE_ADDRESS); | ||
const averageRateUpdateTime = await converter.prevAverageRateUpdateTime.call() | ||
const averageRateUpdateTime = await getPrevAverageRateUpdateTime() | ||
@@ -755,0 +760,0 @@ expect(averageRate.n).not.to.be.bignumber.equal(prevAverageRate.n); |
@@ -5,2 +5,3 @@ const { expect } = require('chai'); | ||
const Decimal = require('decimal.js'); | ||
const { ZERO_ADDRESS, MAX_UINT256 } = constants; | ||
@@ -48,3 +49,3 @@ const ContractRegistry = artifacts.require('ContractRegistry'); | ||
const NUM_OF_DAYS = [30, 100]; | ||
const DECIMAL_COMBINATIONS = cartesian([12, 25], [12, 25], [15, 22], [15, 22]); | ||
const DECIMAL_COMBINATIONS = cartesian([12, 24], [12, 24], [15, 21], [15, 21]); | ||
@@ -64,17 +65,15 @@ const FULL_PPM = percentageToPPM('100%'); | ||
const path = [sourceToken.address, poolToken.address, targetToken.address]; | ||
await bancorNetwork.convertByPath(path, amount, 1, constants.ZERO_ADDRESS, constants.ZERO_ADDRESS, 0); | ||
await bancorNetwork.convertByPath(path, amount, 1, ZERO_ADDRESS, ZERO_ADDRESS, 0); | ||
}; | ||
const increaseRate = async (sourceToken, targetToken, amount) => { | ||
await convert( | ||
sourceToken, | ||
targetToken, | ||
new BN(Decimal(2).sqrt().sub(1).mul(amount.toString()).toFixed(0)) | ||
); | ||
const increaseRate = async (sourceToken, targetToken) => { | ||
const sourceBalance = await converter.reserveBalance(sourceToken.address); | ||
await convert(sourceToken, targetToken, sourceBalance.div(new BN(100))); | ||
}; | ||
const generateFee = async (conversionFee, sourceToken, targetToken, amount) => { | ||
const generateFee = async (conversionFee, sourceToken, targetToken) => { | ||
await converter.setConversionFee(conversionFee); | ||
const prevBalance = await targetToken.balanceOf(owner); | ||
await convert(sourceToken, targetToken, amount.div(new BN(2))); | ||
const sourceBalance = await converter.reserveBalance(sourceToken.address); | ||
await convert(sourceToken, targetToken, sourceBalance.div(new BN(100))); | ||
const currBalance = await targetToken.balanceOf(owner); | ||
@@ -131,4 +130,4 @@ await convert(targetToken, sourceToken, currBalance.sub(prevBalance)); | ||
await baseToken.issue(owner, new BN('1'.padEnd(30, '0'))); | ||
await networkToken.issue(owner, new BN('1'.padEnd(30, '0'))); | ||
await baseToken.issue(owner, new BN('1'.padEnd(40, '0'))); | ||
await networkToken.issue(owner, new BN('1'.padEnd(40, '0'))); | ||
@@ -152,3 +151,3 @@ await converterRegistry.newConverter(1, 'PT', 'PT', 18, FULL_PPM, [baseToken.address, networkToken.address], [HALF_PPM, HALF_PPM]); | ||
await liquidityProtection.whitelistPool(poolToken.address, true); | ||
await liquidityProtection.setSystemNetworkTokenLimits(-1, FULL_PPM); | ||
await liquidityProtection.setSystemNetworkTokenLimits(MAX_UINT256, FULL_PPM); | ||
await liquidityProtection.setAverageRateMaxDeviation(FULL_PPM); | ||
@@ -165,3 +164,3 @@ }); | ||
if (!config.increaseRate && !config.generateFee) { | ||
test = (actual, expected) => condOrAlmostEqual(actual.eq(expected), actual, expected, '0.000000000000001'); | ||
test = (actual, expected) => condOrAlmostEqual(actual.eq(expected), actual, expected, '0.0'); | ||
} | ||
@@ -172,3 +171,3 @@ else if (!config.increaseRate && config.generateFee) { | ||
else if (config.increaseRate && !config.generateFee && numOfDays < 100) { | ||
test = (actual, expected) => condOrAlmostEqual(actual.lt(expected), actual, expected, '0.00000000000000002'); | ||
test = (actual, expected) => condOrAlmostEqual(actual.lt(expected), actual, expected, '0.0'); | ||
} | ||
@@ -186,3 +185,3 @@ else if (config.increaseRate && !config.generateFee && numOfDays >= 100) { | ||
await converter.addLiquidity([baseToken.address, networkToken.address], [amounts[0], amounts[1]], 1); | ||
await addProtectedLiquidity(baseToken, amounts[2]); | ||
@@ -193,11 +192,11 @@ const networkTokenMaxAmount = await getNetworkTokenMaxAmount(); | ||
await addProtectedLiquidity(networkToken, amounts[3]); | ||
if (config.increaseRate) { | ||
await increaseRate(networkToken, baseToken, amounts[3]); | ||
await increaseRate(networkToken, baseToken); | ||
} | ||
if (config.generateFee) { | ||
await generateFee(FEE_PPM, baseToken, networkToken, amounts[2]); | ||
await generateFee(FEE_PPM, baseToken, networkToken); | ||
} | ||
await converter.setTime(timestamp); | ||
@@ -220,6 +219,6 @@ const actual = await liquidityProtection.removeLiquidityReturn(0, FULL_PPM, timestamp); | ||
if (!config.increaseRate && !config.generateFee) { | ||
test = (actual, expected) => condOrAlmostEqual(actual.eq(expected), actual, expected, '0.000000000000002'); | ||
test = (actual, expected) => condOrAlmostEqual(actual.eq(expected), actual, expected, '0.0'); | ||
} | ||
else if (!config.increaseRate && config.generateFee) { | ||
test = (actual, expected) => condOrAlmostEqual(actual.gt(expected), actual, expected, '0.0'); | ||
test = (actual, expected) => condOrAlmostEqual(actual.gt(expected), actual, expected, '0.002'); | ||
} | ||
@@ -230,3 +229,3 @@ else if (config.increaseRate && !config.generateFee && numOfDays < 100) { | ||
else if (config.increaseRate && !config.generateFee && numOfDays >= 100) { | ||
test = (actual, expected) => condOrAlmostEqual(actual.eq(expected), actual, expected, '0.000000002'); | ||
test = (actual, expected) => condOrAlmostEqual(actual.eq(expected), actual, expected, '0.002'); | ||
} | ||
@@ -249,7 +248,7 @@ else { | ||
if (config.increaseRate) { | ||
await increaseRate(baseToken, networkToken, amounts[2]); | ||
await increaseRate(baseToken, networkToken); | ||
} | ||
if (config.generateFee) { | ||
await generateFee(FEE_PPM, networkToken, baseToken, amounts[3]); | ||
await generateFee(FEE_PPM, networkToken, baseToken); | ||
} | ||
@@ -256,0 +255,0 @@ |
@@ -27,2 +27,13 @@ const { expect } = require('chai'); | ||
for (let n = 1; n <= 256; n++) { | ||
for (const k of n < 256 ? [-1, 0, +1] : [-1]) { | ||
const x = new BN(2).pow(new BN(n)).add(new BN(k)); | ||
it(`Function ceilSqrt(0x${x.toString(16)})`, async () => { | ||
const expected = MathUtils.ceilSqrt(x); | ||
const actual = await mathContract.ceilSqrtTest(x); | ||
expect(actual).to.be.bignumber.equal(expected); | ||
}); | ||
} | ||
} | ||
for (const scale of SCALES) { | ||
@@ -29,0 +40,0 @@ for (let a = 0; a < 10; a++) { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1704882
11735