@bancor/contracts-solidity
Advanced tools
Comparing version 0.6.10 to 0.6.11
@@ -0,1 +1,9 @@ | ||
### 0.6.11 (2020-08-18) | ||
LiquidityPoolV2Converter | ||
* Updated weights/fees logic | ||
LiquidTokenConverter | ||
* Initial purchase/supply now takes the reserve weight into account | ||
### 0.6.10 (2020-08-07) | ||
@@ -2,0 +10,0 @@ LiquidityPoolV2Converter |
{ | ||
"name": "@bancor/contracts-solidity", | ||
"version": "0.6.10", | ||
"version": "0.6.11", | ||
"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": { |
@@ -90,3 +90,3 @@ const { expect } = require('chai'); | ||
const MIN_RETURN = new BN(1); | ||
const WEIGHT_RESOLUTION = new BN(1000000); | ||
const PPM_RESOLUTION = new BN(1000000); | ||
@@ -152,3 +152,3 @@ before(async () => { | ||
_token2: reserveToken.address, | ||
_rateN: reserve1Balance.mul(WEIGHT_RESOLUTION), | ||
_rateN: reserve1Balance.mul(PPM_RESOLUTION), | ||
_rateD: poolTokenSupply.mul(reserve1Weight) | ||
@@ -160,3 +160,3 @@ }); | ||
_token2: reserveToken2.address, | ||
_rateN: reserve2Balance.mul(WEIGHT_RESOLUTION), | ||
_rateN: reserve2Balance.mul(PPM_RESOLUTION), | ||
_rateD: poolTokenSupply.mul(reserve2Weight) | ||
@@ -180,3 +180,3 @@ }); | ||
_token2: reserveToken.address, | ||
_rateN: reserve1Balance.mul(WEIGHT_RESOLUTION), | ||
_rateN: reserve1Balance.mul(PPM_RESOLUTION), | ||
_rateD: poolTokenSupply.mul(reserve1Weight) | ||
@@ -188,3 +188,3 @@ }); | ||
_token2: reserveToken2.address, | ||
_rateN: reserve2Balance.mul(WEIGHT_RESOLUTION), | ||
_rateN: reserve2Balance.mul(PPM_RESOLUTION), | ||
_rateD: poolTokenSupply.mul(reserve2Weight) | ||
@@ -257,3 +257,3 @@ }); | ||
expect(event2._token2).to.eql(getReserve1Address(isETHReserve)); | ||
expect(event2._rateN).to.be.bignumber.equal(reserve1Balance.mul(WEIGHT_RESOLUTION)); | ||
expect(event2._rateN).to.be.bignumber.equal(reserve1Balance.mul(PPM_RESOLUTION)); | ||
expect(event2._rateD).to.be.bignumber.equal(poolTokenSupply.mul(reserve1Weight)); | ||
@@ -265,3 +265,3 @@ | ||
expect(event3._token2).to.eql(reserveToken2.address); | ||
expect(event3._rateN).to.be.bignumber.equal(reserve2Balance.mul(WEIGHT_RESOLUTION)); | ||
expect(event3._rateN).to.be.bignumber.equal(reserve2Balance.mul(PPM_RESOLUTION)); | ||
expect(event3._rateD).to.be.bignumber.equal(poolTokenSupply.mul(reserve2Weight)); | ||
@@ -268,0 +268,0 @@ }); |
const { expect } = require('chai'); | ||
const { BN } = require('@openzeppelin/test-helpers'); | ||
const Decimal = require('decimal.js'); | ||
const MathUtils = require('./helpers/MathUtils'); | ||
const LiquidityPoolV2Converter = artifacts.require('TestLiquidityPoolV2Converter'); | ||
@@ -9,2 +12,5 @@ | ||
const ILLEGAL_VAL = Decimal(2).pow(256); | ||
const SCALES = [6, 18, 30].map(n => Decimal(10).pow(n)); | ||
before(async () => { | ||
@@ -15,20 +21,131 @@ const DUMMY_ADDRESS = '0x'.padEnd(42, 'f'); | ||
describe('dynamic-fee:', () => { | ||
const AMPLIFICATION_FACTOR = new BN(20); | ||
const stakedValues = [1234, 2345, 3456, 4567, 5678, 6789].map(x => AMPLIFICATION_FACTOR.mul(new BN(x))); | ||
const factorValues = [0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0].map(x => new BN(x * 10000)); | ||
const tknWeight = new BN(1); | ||
const bntWeight = new BN(1); | ||
const tknRate = new BN(1); | ||
const bntRate = new BN(1); | ||
for (const scale of SCALES) { | ||
for (let a = 0; a < 10; a++) { | ||
for (let b = 1; b <= 10; b++) { | ||
it(`normalizedRatio(${a}, ${b}, ${scale.toFixed()})`, async () => { | ||
const expectedRatio = MathUtils.normalizedRatio(a, b, scale); | ||
const expectedX = expectedRatio[0]; | ||
const expectedY = expectedRatio[1]; | ||
const actualRatio = await converter.normalizedRatioTest.call(a, b, scale.toFixed()); | ||
const actualX = actualRatio[0]; | ||
const actualY = actualRatio[1]; | ||
expect(actualX).to.be.bignumber.equal(expectedX); | ||
expect(actualY).to.be.bignumber.equal(expectedY); | ||
}); | ||
} | ||
} | ||
for (const tknStaked of stakedValues) { | ||
for (const bntStaked of stakedValues) { | ||
for (const feeFactor of factorValues) { | ||
const x = tknStaked.mul(tknRate).mul(bntWeight); | ||
const y = bntStaked.mul(bntRate).mul(tknWeight); | ||
const expected = y.gt(x) ? y.sub(x).mul(feeFactor).mul(AMPLIFICATION_FACTOR).div(y) : new BN(0); | ||
it(`calculateFeeToEquilibrium(${[tknStaked, bntStaked, tknWeight, bntWeight, tknRate, bntRate, feeFactor]}) = ${expected.toString()}`, async () => { | ||
const actual = await converter.calculateFeeToEquilibriumTest.call(tknStaked, bntStaked, tknWeight, bntWeight, tknRate, bntRate, feeFactor); | ||
expect(actual).to.be.bignumber.equal(expected); | ||
for (let i = Decimal(1); i.lte(scale); i = i.mul(10)) { | ||
const a = ILLEGAL_VAL.sub(1).divToInt(scale).mul(i).add(1); | ||
for (let j = Decimal(1); j.lte(scale); j = j.mul(10)) { | ||
const b = ILLEGAL_VAL.sub(1).divToInt(scale).mul(j).add(1); | ||
it(`normalizedRatio(${a.toFixed()}, ${b.toFixed()}, ${scale.toFixed()})`, async () => { | ||
const expectedRatio = MathUtils.normalizedRatio(a, b, scale); | ||
const expectedX = expectedRatio[0]; | ||
const expectedY = expectedRatio[1]; | ||
const actualRatio = await converter.normalizedRatioTest.call(a.toFixed(), b.toFixed(), scale.toFixed()); | ||
const actualX = actualRatio[0]; | ||
const actualY = actualRatio[1]; | ||
expect(actualX).to.be.bignumber.equal(expectedX); | ||
expect(actualY).to.be.bignumber.equal(expectedY); | ||
}); | ||
} | ||
} | ||
for (let a = 0; a < 10; a++) { | ||
for (let b = Math.max(a, 1); b <= 10; b++) { | ||
it(`accurateRatio(${a}, ${b}, ${scale.toFixed()})`, async () => { | ||
const expectedRatio = MathUtils.accurateRatio(a, b, scale); | ||
const expectedX = expectedRatio[0]; | ||
const expectedY = expectedRatio[1]; | ||
const actualRatio = await converter.accurateRatioTest.call(a, b, scale.toFixed()); | ||
const actualX = actualRatio[0]; | ||
const actualY = actualRatio[1]; | ||
expect(actualX).to.be.bignumber.equal(expectedX); | ||
expect(actualY).to.be.bignumber.equal(expectedY); | ||
}); | ||
} | ||
} | ||
for (let i = Decimal(1); i.lte(scale); i = i.mul(10)) { | ||
const a = ILLEGAL_VAL.sub(1).divToInt(scale).mul(i).add(1); | ||
for (let j = Decimal(1); j.lte(scale); j = j.mul(10)) { | ||
const b = ILLEGAL_VAL.sub(1).divToInt(scale).mul(j).add(1); | ||
it(`accurateRatio(${a.toFixed()}, ${b.toFixed()}, ${scale.toFixed()})`, async () => { | ||
const expectedRatio = MathUtils.accurateRatio(a, b, scale); | ||
const expectedX = expectedRatio[0]; | ||
const expectedY = expectedRatio[1]; | ||
const actualRatio = await converter.accurateRatioTest.call(a.toFixed(), b.toFixed(), scale.toFixed()); | ||
const actualX = actualRatio[0]; | ||
const actualY = actualRatio[1]; | ||
expect(actualX).to.be.bignumber.equal(expectedX); | ||
expect(actualY).to.be.bignumber.equal(expectedY); | ||
}); | ||
} | ||
} | ||
for (let a = 0; a < 10; a++) { | ||
for (let b = 1; b <= 10; b++) { | ||
it(`reducedRatio(${a}, ${b}, ${scale.toFixed()})`, async () => { | ||
const expectedRatio = MathUtils.reducedRatio(a, b, scale); | ||
const expectedX = expectedRatio[0]; | ||
const expectedY = expectedRatio[1]; | ||
const actualRatio = await converter.reducedRatioTest.call(a, b, scale.toFixed()); | ||
const actualX = actualRatio[0]; | ||
const actualY = actualRatio[1]; | ||
expect(actualX).to.be.bignumber.equal(expectedX); | ||
expect(actualY).to.be.bignumber.equal(expectedY); | ||
}); | ||
} | ||
} | ||
for (let i = Decimal(1); i.lte(scale); i = i.mul(10)) { | ||
const a = ILLEGAL_VAL.sub(1).divToInt(scale).mul(i).add(1); | ||
for (let j = Decimal(1); j.lte(scale); j = j.mul(10)) { | ||
const b = ILLEGAL_VAL.sub(1).divToInt(scale).mul(j).add(1); | ||
it(`reducedRatio(${a.toFixed()}, ${b.toFixed()}, ${scale.toFixed()})`, async () => { | ||
const expectedRatio = MathUtils.reducedRatio(a, b, scale); | ||
const expectedX = expectedRatio[0]; | ||
const expectedY = expectedRatio[1]; | ||
const actualRatio = await converter.reducedRatioTest.call(a.toFixed(), b.toFixed(), scale.toFixed()); | ||
const actualX = actualRatio[0]; | ||
const actualY = actualRatio[1]; | ||
expect(actualX).to.be.bignumber.equal(expectedX); | ||
expect(actualY).to.be.bignumber.equal(expectedY); | ||
}); | ||
} | ||
} | ||
} | ||
for (let n = 0; n < 10; n++) { | ||
for (let d = 1; d <= 10; d++) { | ||
it(`roundDiv(${n}, ${d})`, async () => { | ||
const expected = MathUtils.roundDiv(n, d); | ||
const actual = await converter.roundDivTest.call(n, d); | ||
expect(actual).to.be.bignumber.equal(expected); | ||
}); | ||
} | ||
} | ||
for (const i of [-2, -1, 0, 1, 2]) { | ||
const n = ILLEGAL_VAL.add(i).mod(ILLEGAL_VAL); | ||
for (const j of [-2, -1, 1, 2]) { | ||
const d = ILLEGAL_VAL.add(j).mod(ILLEGAL_VAL); | ||
it(`roundDiv(${n.toFixed()}, ${d.toFixed()})`, async () => { | ||
const expected = MathUtils.roundDiv(n, d); | ||
const actual = await converter.roundDivTest.call(n.toFixed(), d.toFixed()); | ||
expect(actual).to.be.bignumber.equal(expected); | ||
}); | ||
} | ||
} | ||
for (let a = 1; a < 5; a++) { | ||
for (let b = 1; b < 5; b++) { | ||
for (let p = 1; p < 5; p++) { | ||
for (let q = p; q < 5; q++) { | ||
const expected = MathUtils.weightedAverageIntegers(a, b, p, q); | ||
it(`weightedAverageIntegers(${[a, b, p, q]}) should return ${expected}`, async () => { | ||
const retVal = await converter.weightedAverageIntegersTest.call(a, b, p, q); | ||
const actual = Decimal(retVal.toString()); | ||
expect(actual.sub(expected).abs().lte(1)).to.be.true(`but returned ${actual}`); | ||
}); | ||
@@ -38,3 +155,44 @@ } | ||
} | ||
}); | ||
} | ||
for (const a of [20, 25, 30].map(x => '1'.padEnd(x, '0'))) { | ||
for (const b of [20, 25, 30].map(x => '1'.padEnd(x, '0'))) { | ||
const p = 999999; | ||
const q = 999999; | ||
const expected = MathUtils.weightedAverageIntegers(a, b, p, q); | ||
it(`weightedAverageIntegers(${[a, b, p, q]}) should return ${expected}`, async () => { | ||
const retVal = await converter.weightedAverageIntegersTest.call(a, b, p, q); | ||
const actual = Decimal(retVal.toString()); | ||
expect(actual.sub(expected).abs().lte(1)).to.be.true(`but returned ${actual}`); | ||
}); | ||
} | ||
} | ||
for (let a = 1; a < 5; a++) { | ||
for (let b = 1; b < 5; b++) { | ||
for (let c = 1; c < 5; c++) { | ||
for (let d = 1; d < 5; d++) { | ||
const expected = MathUtils.compareRates(a, b, c, d); | ||
it(`compareRates(${[a, b, c, d]}) should return ${expected}`, async () => { | ||
const actual = await converter.compareRatesTest.call(a, b, c, d); | ||
expect(actual).to.be.bignumber.equal(expected.toString()); | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
for (const a of [20, 25, 30].map(x => '1'.padEnd(x, '0'))) { | ||
for (const b of [20, 25, 30].map(x => '1'.padEnd(x, '0'))) { | ||
for (const c of [20, 25, 30].map(x => '1'.padEnd(x, '0'))) { | ||
for (const d of [20, 25, 30].map(x => '1'.padEnd(x, '0'))) { | ||
const expected = MathUtils.compareRates(a, b, c, d); | ||
it(`compareRates(${[a, b, c, d]}) should return ${expected}`, async () => { | ||
const actual = await converter.compareRatesTest.call(a, b, c, d); | ||
expect(actual).to.be.bignumber.equal(expected.toString()); | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
}); |
@@ -86,5 +86,5 @@ const { expect } = require('chai'); | ||
const MIN_RETURN = new BN(1); | ||
const WEIGHT_RESOLUTION = new BN(1000000); | ||
const WEIGHT_10_PERCENT = new BN(100000); | ||
const WEIGHT_20_PERCENT = new BN(200000); | ||
const WEIGHT_100_PERCENT = new BN(1000000); | ||
@@ -311,3 +311,3 @@ before(async () => { | ||
expect(_token2).to.eql(getReserve1Address(isETHReserve)); | ||
expect(_rateN).to.be.bignumber.equal(reserveBalance.mul(WEIGHT_RESOLUTION)); | ||
expect(_rateN).to.be.bignumber.equal(reserveBalance.mul(WEIGHT_100_PERCENT)); | ||
expect(_rateD).to.be.bignumber.equal(supply.mul(reserveWeight)); | ||
@@ -314,0 +314,0 @@ }); |
@@ -215,5 +215,4 @@ const fs = require('fs'); | ||
const converterBase = deployed(web3, 'ConverterBase', await anchor.methods.owner().call()); | ||
await execute(converterBase.methods.acceptOwnership()); | ||
await execute(converterBase.methods.setConversionFee(fee)); | ||
await execute(converterBase.methods.acceptOwnership()); | ||
@@ -220,0 +219,0 @@ if (type !== 0 && amounts.every(amount => amount > 0)) { |
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
2135039
354
9812