Skip to content

Commit cbcd4d9

Browse files
committed
Add external position modules check to #_validateTradeParameters
1 parent f4dc455 commit cbcd4d9

File tree

2 files changed

+61
-41
lines changed

2 files changed

+61
-41
lines changed

contracts/protocol/modules/GeneralIndexModule.sol

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,7 @@ contract GeneralIndexModule is ModuleBase, ReentrancyGuard {
195195
);
196196

197197
for (uint256 i = 0; i < aggregateComponents.length; i++) {
198-
require(
199-
_setToken.getExternalPositionModules(aggregateComponents[i]).length == 0,
200-
"External positions not allowed"
201-
);
202-
198+
require(!_setToken.hasExternalPosition(aggregateComponents[i]), "External positions not allowed");
203199
executionInfo[_setToken][IERC20(aggregateComponents[i])].targetUnit = aggregateTargetUnits[i];
204200
emit TargetUnitsUpdated(_setToken, aggregateComponents[i], aggregateTargetUnits[i], _positionMultiplier);
205201
}
@@ -636,6 +632,8 @@ contract GeneralIndexModule is ModuleBase, ReentrancyGuard {
636632
componentInfo.lastTradeTimestamp.add(componentInfo.coolOffPeriod) <= block.timestamp,
637633
"Component cool off in progress"
638634
);
635+
636+
require(!_setToken.hasExternalPosition(address(_component)), "External positions not allowed");
639637
}
640638

641639
/**

test/protocol/modules/generalIndexModule.spec.ts

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ describe("GeneralIndexModule", () => {
4343

4444
let index: SetToken;
4545
let indexWithWeth: SetToken;
46-
let indexWithPositionModule: SetToken;
4746
let indexModule: GeneralIndexModule;
4847

4948
let balancerExchangeAdapter: BalancerV1IndexExchangeAdapter;
@@ -111,7 +110,7 @@ describe("GeneralIndexModule", () => {
111110
index = await setup.createSetToken(
112111
indexComponents,
113112
indexUnits, // $100 of each
114-
[setup.issuanceModule.address, setup.streamingFeeModule.address, indexModule.address],
113+
[setup.issuanceModule.address, setup.streamingFeeModule.address, indexModule.address, positionModule.address],
115114
);
116115

117116
const feeSettings = {
@@ -123,13 +122,7 @@ describe("GeneralIndexModule", () => {
123122

124123
await setup.streamingFeeModule.initialize(index.address, feeSettings);
125124
await setup.issuanceModule.initialize(index.address, ADDRESS_ZERO);
126-
127-
indexWithPositionModule = await setup.createSetToken(
128-
indexComponents,
129-
indexUnits,
130-
[positionModule.address, indexModule.address]
131-
);
132-
await indexWithPositionModule.connect(positionModule.wallet).initializeModule();
125+
await index.connect(positionModule.wallet).initializeModule();
133126

134127
indexWithWethComponents = [uniswapSetup.uni.address, setup.wbtc.address, setup.dai.address, setup.weth.address];
135128
indexWithWethUnits = [ether(86.9565217), bitcoin(.01111111), ether(100), ether(0.434782609)];
@@ -256,25 +249,24 @@ describe("GeneralIndexModule", () => {
256249
});
257250

258251
describe("when there are external positions for a component", async () => {
259-
beforeEach(async () => {
260-
subjectSetToken = indexWithPositionModule;
261-
await subjectSetToken.connect(positionModule.wallet).addExternalPositionModule(
262-
indexComponents[0],
263-
positionModule.address
264-
);
265-
});
252+
beforeEach(async () => {
253+
await subjectSetToken.connect(positionModule.wallet).addExternalPositionModule(
254+
indexComponents[0],
255+
positionModule.address
256+
);
257+
});
266258

267-
afterEach(async () => {
268-
await subjectSetToken.connect(positionModule.wallet).removeExternalPositionModule(
269-
indexComponents[0],
270-
positionModule.address
271-
);
272-
});
259+
afterEach(async () => {
260+
await subjectSetToken.connect(positionModule.wallet).removeExternalPositionModule(
261+
indexComponents[0],
262+
positionModule.address
263+
);
264+
});
273265

274-
it("should revert", async() => {
275-
await expect(subject()).to.be.revertedWith("External positions not allowed");
276-
});
266+
it("should revert", async() => {
267+
await expect(subject()).to.be.revertedWith("External positions not allowed");
277268
});
269+
});
278270
});
279271

280272
describe("when module is initalized", async () => {
@@ -313,14 +305,6 @@ describe("GeneralIndexModule", () => {
313305
[uniswapAdapterName, sushiswapAdapterName, balancerAdapterName, "", sushiswapAdapterName],
314306
[ONE_MINUTE_IN_SECONDS.mul(3), ONE_MINUTE_IN_SECONDS, ONE_MINUTE_IN_SECONDS.mul(2), ZERO, ONE_MINUTE_IN_SECONDS],
315307
);
316-
317-
await initSetToken(
318-
indexWithPositionModule,
319-
[uniswapSetup.uni.address, setup.wbtc.address, setup.dai.address, sushiswapSetup.uni.address],
320-
[ether(800), bitcoin(.1), ether(1000), ether(500)],
321-
[uniswapAdapterName, sushiswapAdapterName, balancerAdapterName, sushiswapAdapterName],
322-
[ONE_MINUTE_IN_SECONDS.mul(3), ONE_MINUTE_IN_SECONDS, ONE_MINUTE_IN_SECONDS.mul(2), ONE_MINUTE_IN_SECONDS]
323-
);
324308
});
325309

326310
describe("#startRebalance", async () => {
@@ -411,8 +395,6 @@ describe("GeneralIndexModule", () => {
411395

412396
describe("when there are external positions for a component", async () => {
413397
beforeEach(async () => {
414-
subjectSetToken = indexWithPositionModule;
415-
416398
await subjectSetToken.connect(positionModule.wallet).addExternalPositionModule(
417399
subjectNewComponents[0],
418400
positionModule.address
@@ -427,7 +409,7 @@ describe("GeneralIndexModule", () => {
427409
});
428410

429411
it("should revert", async() => {
430-
await expect(subject()).to.be.revertedWith("External positions not allowed");
412+
await expect(subject()).to.be.revertedWith("External positions not allowed");
431413
});
432414
});
433415
});
@@ -1081,6 +1063,26 @@ describe("GeneralIndexModule", () => {
10811063
});
10821064
});
10831065

1066+
describe("when there are external positions for a component", async () => {
1067+
beforeEach(async () => {
1068+
await subjectSetToken.connect(positionModule.wallet).addExternalPositionModule(
1069+
subjectComponent,
1070+
positionModule.address
1071+
);
1072+
});
1073+
1074+
afterEach(async () => {
1075+
await subjectSetToken.connect(positionModule.wallet).removeExternalPositionModule(
1076+
subjectComponent,
1077+
positionModule.address
1078+
);
1079+
});
1080+
1081+
it("should revert", async() => {
1082+
await expect(subject()).to.be.revertedWith("External positions not allowed");
1083+
});
1084+
});
1085+
10841086
describe("when caller is a contract", async () => {
10851087
let subjectTarget: Address;
10861088
let subjectCallData: string;
@@ -1662,6 +1664,26 @@ describe("GeneralIndexModule", () => {
16621664
});
16631665
});
16641666

1667+
describe("when there are external positions for a component", async () => {
1668+
beforeEach(async () => {
1669+
await subjectSetToken.connect(positionModule.wallet).addExternalPositionModule(
1670+
subjectComponent,
1671+
positionModule.address
1672+
);
1673+
});
1674+
1675+
afterEach(async () => {
1676+
await subjectSetToken.connect(positionModule.wallet).removeExternalPositionModule(
1677+
subjectComponent,
1678+
positionModule.address
1679+
);
1680+
});
1681+
1682+
it("should revert", async() => {
1683+
await expect(subject()).to.be.revertedWith("External positions not allowed");
1684+
});
1685+
});
1686+
16651687
describe("when the calling address is not a permissioned address", async () => {
16661688
beforeEach(async () => {
16671689
subjectCaller = await getRandomAccount();

0 commit comments

Comments
 (0)