Skip to content

Commit

Permalink
Merge branch 'master' into managed-swap-fees
Browse files Browse the repository at this point in the history
* master:
  Cache token weight in _onSwapGivenIn/Out (#1769)
  Fix deployments package (#1773)
  Avoid double zero duration check in `calculateValueChangeProgress` (#1772)
  Extend PoolRegLib (#1770)
  • Loading branch information
TomAFrench committed Sep 15, 2022
2 parents bbb1080 + ccb2f51 commit 711e450
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 99 deletions.
26 changes: 26 additions & 0 deletions pkg/pool-utils/contracts/lib/PoolRegistrationLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,30 @@ library PoolRegistrationLib {

return poolId;
}

function registerToken(
IVault vault,
bytes32 poolId,
IERC20 token,
address assetManager
) internal {
IERC20[] memory tokens = new IERC20[](1);
tokens[0] = token;

address[] memory assetManagers = new address[](1);
assetManagers[0] = assetManager;

vault.registerTokens(poolId, tokens, assetManagers);
}

function deregisterToken(
IVault vault,
bytes32 poolId,
IERC20 token
) internal {
IERC20[] memory tokens = new IERC20[](1);
tokens[0] = token;

vault.deregisterTokens(poolId, tokens);
}
}
17 changes: 17 additions & 0 deletions pkg/pool-utils/contracts/test/MockPoolRegistrationLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,21 @@ contract MockPoolRegistrationLib {
) external returns (bytes32) {
return PoolRegistrationLib.registerPoolWithAssetManagers(vault, specialization, tokens, assetManagers);
}

function registerToken(
IVault vault,
bytes32 poolId,
IERC20 token,
address assetManager
) external {
PoolRegistrationLib.registerToken(vault, poolId, token, assetManager);
}

function deregisterToken(
IVault vault,
bytes32 poolId,
IERC20 token
) external {
PoolRegistrationLib.deregisterToken(vault, poolId, token);
}
}
155 changes: 102 additions & 53 deletions pkg/pool-utils/test/PoolRegistrationLib.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { deploy } from '@balancer-labs/v2-helpers/src/contract';
import { PoolSpecialization } from '@balancer-labs/balancer-js';
import Vault from '@balancer-labs/v2-helpers/src/models/vault/Vault';
import Token from '@balancer-labs/v2-helpers/src/models/tokens/Token';
import { ZERO_ADDRESS } from '@balancer-labs/v2-helpers/src/constants';
import { randomAddress, ZERO_ADDRESS } from '@balancer-labs/v2-helpers/src/constants';

describe('PoolRegistrationLib', function () {
let vault: Vault;
Expand All @@ -35,74 +35,123 @@ describe('PoolRegistrationLib', function () {
return event.args.poolId;
}

it('registers the pool in the vault', async () => {
const poolId = await registerPool(PoolSpecialization.GeneralPool);
describe('registerPool', () => {
it('registers the pool in the vault', async () => {
const poolId = await registerPool(PoolSpecialization.GeneralPool);

const { address: poolAddress } = await vault.getPool(poolId);
expect(poolAddress).to.equal(lib.address);
});
const { address: poolAddress } = await vault.getPool(poolId);
expect(poolAddress).to.equal(lib.address);
});

it('registers the pool with the correct specialization', async () => {
const specializations: (keyof typeof PoolSpecialization)[] = ['GeneralPool', 'MinimalSwapInfoPool', 'TwoTokenPool'];
for (const specialization of specializations) {
const poolId = await registerPool(PoolSpecialization[specialization]);
const { specialization: poolSpecialization } = await vault.getPool(poolId);
expect(poolSpecialization).to.equal(PoolSpecialization[specialization]);
}
});
it('registers the pool with the correct specialization', async () => {
const specializations: (keyof typeof PoolSpecialization)[] = [
'GeneralPool',
'MinimalSwapInfoPool',
'TwoTokenPool',
];
for (const specialization of specializations) {
const poolId = await registerPool(PoolSpecialization[specialization]);
const { specialization: poolSpecialization } = await vault.getPool(poolId);
expect(poolSpecialization).to.equal(PoolSpecialization[specialization]);
}
});

it('registers the tokens correctly', async () => {
const poolId = await registerPool(PoolSpecialization.GeneralPool);
const { tokens: poolTokens } = await vault.getPoolTokens(poolId);
expect(poolTokens).to.deep.eq(tokens.addresses);
});
it('registers the tokens correctly', async () => {
const poolId = await registerPool(PoolSpecialization.GeneralPool);
const { tokens: poolTokens } = await vault.getPoolTokens(poolId);
expect(poolTokens).to.deep.eq(tokens.addresses);
});

it('reverts if the tokens are not sorted', async () => {
await expect(
lib.registerPool(vault.address, PoolSpecialization.GeneralPool, tokens.addresses.reverse())
).to.be.revertedWith('UNSORTED_ARRAY');
});
it('reverts if the tokens are not sorted', async () => {
await expect(
lib.registerPool(vault.address, PoolSpecialization.GeneralPool, tokens.addresses.reverse())
).to.be.revertedWith('UNSORTED_ARRAY');
});

context('when passing asset managers', () => {
context("when the token and asset managers arrays' lengths are mismatched", () => {
it('reverts', async () => {
const tooManyAssetManagers = Array.from(
{ length: tokens.length + 1 },
() => ethers.Wallet.createRandom().address
);

await expect(
lib.registerPoolWithAssetManagers(
vault.address,
PoolSpecialization.GeneralPool,
tokens.addresses,
tooManyAssetManagers
)
).to.be.revertedWith('INPUT_LENGTH_MISMATCH');
});
});

context("when the token and asset managers arrays' lengths match", () => {
it('registers the asset managers correctly', async () => {
const assetManagers = tokens.map(() => ethers.Wallet.createRandom().address);
const poolId = await registerPool(PoolSpecialization.GeneralPool, assetManagers);

context('when passing asset managers', () => {
context("when the token and asset managers arrays' lengths are mismatched", () => {
it('reverts', async () => {
const tooManyAssetManagers = Array.from(
{ length: tokens.length + 1 },
() => ethers.Wallet.createRandom().address
);

await expect(
lib.registerPoolWithAssetManagers(
vault.address,
PoolSpecialization.GeneralPool,
tokens.addresses,
tooManyAssetManagers
)
).to.be.revertedWith('INPUT_LENGTH_MISMATCH');
await tokens.asyncEach(async (token: Token, i: number) => {
const { assetManager } = await vault.getPoolTokenInfo(poolId, token);
expect(assetManager).to.equal(assetManagers[i]);
});
});
});
});

context("when the token and asset managers arrays' lengths match", () => {
it('registers the asset managers correctly', async () => {
const assetManagers = tokens.map(() => ethers.Wallet.createRandom().address);
const poolId = await registerPool(PoolSpecialization.GeneralPool, assetManagers);
context('when not passing asset managers', () => {
it("doesn't register asset managers", async () => {
const poolId = await registerPool(PoolSpecialization.GeneralPool);

await tokens.asyncEach(async (token: Token, i: number) => {
await tokens.asyncEach(async (token: Token) => {
const { assetManager } = await vault.getPoolTokenInfo(poolId, token);
expect(assetManager).to.equal(assetManagers[i]);
expect(assetManager).to.equal(ZERO_ADDRESS);
});
});
});
});

context('when not passing asset managers', () => {
it("doesn't register asset managers", async () => {
const poolId = await registerPool(PoolSpecialization.GeneralPool);
describe('registerToken', () => {
let poolId: string;

await tokens.asyncEach(async (token: Token) => {
const { assetManager } = await vault.getPoolTokenInfo(poolId, token);
expect(assetManager).to.equal(ZERO_ADDRESS);
});
sharedBeforeEach(async () => {
poolId = await registerPool(PoolSpecialization.GeneralPool);
});

it('registers a new token', async () => {
const token = await randomAddress();
const assetManager = await randomAddress();
await lib.registerToken(vault.address, poolId, token, assetManager);

const { tokens: actualTokens } = await vault.getPoolTokens(poolId);
expect(actualTokens).to.include(token);
});

it('registers the asset manager', async () => {
const token = await randomAddress();
const assetManager = await randomAddress();
await lib.registerToken(vault.address, poolId, token, assetManager);

const { assetManager: actualAssetManager } = await vault.getPoolTokenInfo(poolId, token);
expect(actualAssetManager).to.equal(assetManager);
});
});

describe('deregisterToken', () => {
let poolId: string;

sharedBeforeEach(async () => {
poolId = await registerPool(PoolSpecialization.GeneralPool);
});

it('deregisters a token', async () => {
const token = tokens.first.address;

await lib.deregisterToken(vault.address, poolId, token);

const { tokens: actualTokens } = await vault.getPoolTokens(poolId);
expect(actualTokens).to.not.include(token);
});
});
});
14 changes: 7 additions & 7 deletions pkg/pool-weighted/contracts/lib/GradualValueChange.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ library GradualValueChange {

if (startValue > endValue) {
uint256 delta = pctProgress.mulDown(startValue - endValue);
return startValue.sub(delta);
return startValue - delta;
} else {
uint256 delta = pctProgress.mulDown(endValue - startValue);
return startValue.add(delta);
return startValue + delta;
}
}

Expand All @@ -67,17 +67,17 @@ library GradualValueChange {
function calculateValueChangeProgress(uint256 startTime, uint256 endTime) internal view returns (uint256) {
uint256 currentTime = block.timestamp;

if (currentTime > endTime) {
if (currentTime >= endTime) {
return FixedPoint.ONE;
} else if (currentTime < startTime) {
} else if (currentTime <= startTime) {
return 0;
}

// No need for SafeMath as it was checked right above: endTime >= currentTime >= startTime
// No need for SafeMath as it was checked right above: endTime > currentTime > startTime
uint256 totalSeconds = endTime - startTime;
uint256 secondsElapsed = currentTime - startTime;

// In the degenerate case of a zero duration change, consider it completed (and avoid division by zero)
return totalSeconds == 0 ? FixedPoint.ONE : secondsElapsed.divDown(totalSeconds);
// We don't need to consider zero division here as this is covered above.
return secondsElapsed.divDown(totalSeconds);
}
}
Loading

0 comments on commit 711e450

Please sign in to comment.