Skip to content

Update register flow on CLM #14

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 6 commits into from
Jan 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions contracts/protocol/modules/CompoundLeverageModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ contract CompoundLeverageModule is ModuleBase, ReentrancyGuard {

/* ============ Constants ============ */

// String identifying the DebtIssuanceModule in the IntegrationRegistry. Note: Governance must add DefaultIssuanceModule as
// the string as the integration name
string constant internal DEFAULT_ISSUANCE_MODULE_NAME = "DefaultIssuanceModule";

// 0 index stores protocol fee % on the controller, charged in the trade function
uint256 constant internal PROTOCOL_TRADE_FEE_INDEX = 0;

Expand Down Expand Up @@ -494,6 +498,10 @@ contract CompoundLeverageModule is ModuleBase, ReentrancyGuard {
// Initialize module before trying register
_setToken.initializeModule();

// Get debt issuance module registered to this module and require that it is initialized
address debtIssuanceModule = getAndValidateAdapter(DEFAULT_ISSUANCE_MODULE_NAME);
require(_setToken.isInitializedModule(debtIssuanceModule), "Debt issuance module must be initialized on SetToken");

// Try if register exists on any of the modules
address[] memory modules = _setToken.getModules();
for(uint256 i = 0; i < modules.length; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Problem here is that it wouldn't register with a compatible NAVIssuanceModule. We may want to keep the same flow just do a check that validates it's been added as a module to the SetToken before it starts iterating through the modules

Expand Down
116 changes: 96 additions & 20 deletions test/protocol/modules/compoundLeverageModule.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,13 @@ describe("CompoundLeverageModule", () => {
"ONEINCHSLIPPAGE",
oneInchExchangeAdapterWithSlippage.address
);

// Add debt issuance address to integration
await setup.integrationRegistry.addIntegration(
compoundLeverageModule.address,
"DefaultIssuanceModule",
debtIssuanceMock.address
);
});

addSnapshotBeforeRestoreAfterEach();
Expand Down Expand Up @@ -324,6 +331,40 @@ describe("CompoundLeverageModule", () => {
expect(isRegistered).to.be.true;
});

describe("when debt issuance module is not added to integration registry", async () => {
beforeEach(async () => {
await setup.integrationRegistry.removeIntegration(compoundLeverageModule.address, "DefaultIssuanceModule");
});

afterEach(async () => {
// Add debt issuance address to integration
await setup.integrationRegistry.addIntegration(
compoundLeverageModule.address,
"DefaultIssuanceModule",
debtIssuanceMock.address
);
});

it("should revert", async () => {
await expect(subject()).to.be.revertedWith("Must be valid adapter");
});
});

describe("when debt issuance module is not initialized on SetToken", async () => {
beforeEach(async () => {
await setToken.removeModule(debtIssuanceMock.address);
});

afterEach(async () => {
await setToken.addModule(debtIssuanceMock.address);
await debtIssuanceMock.initialize(setToken.address);
});

it("should revert", async () => {
await expect(subject()).to.be.revertedWith("Debt issuance module must be initialized on SetToken");
});
});

describe("when collateral asset does not exist on Compound", async () => {
beforeEach(async () => {
subjectCollateralAssets = [setup.dai.address, await getRandomAddress()];
Expand Down Expand Up @@ -2093,14 +2134,22 @@ describe("CompoundLeverageModule", () => {
"ONEINCHCOMP",
oneInchExchangeAdapterFromComp.address
);

// Add debt issuance address to integration
await setup.integrationRegistry.addIntegration(
secondCompoundLeverageModule.address,
"DefaultIssuanceModule",
debtIssuanceMock.address
);
});

beforeEach(async () => {
setToken = await setup.createSetToken(
[cEther.address],
[BigNumber.from(10000000000)],
[secondCompoundLeverageModule.address, setup.issuanceModule.address]
[secondCompoundLeverageModule.address, setup.issuanceModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
await gulpComptrollerMock.addSetTokenAddress(setToken.address);
// Initialize module if set to true
if (isInitialized) {
Expand Down Expand Up @@ -2428,12 +2477,19 @@ describe("CompoundLeverageModule", () => {
"ONEINCHCOMP",
oneInchExchangeAdapterFromComp.address
);
// Add debt issuance address to integration
await setup.integrationRegistry.addIntegration(
secondCompoundLeverageModule.address,
"DefaultIssuanceModule",
debtIssuanceMock.address
);

setToken = await setup.createSetToken(
[cEther.address, compoundSetup.comp.address],
[BigNumber.from(10000000000), ether(10)],
[secondCompoundLeverageModule.address, setup.issuanceModule.address]
[secondCompoundLeverageModule.address, setup.issuanceModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
await gulpComptrollerMock.addSetTokenAddress(setToken.address);
// Initialize module if set to true
await secondCompoundLeverageModule.initialize(
Expand Down Expand Up @@ -2549,12 +2605,19 @@ describe("CompoundLeverageModule", () => {
"ONEINCHUNUSED",
oneInchExchangeAdapterToWeth.address
);
// Add debt issuance address to integration
await setup.integrationRegistry.addIntegration(
secondCompoundLeverageModule.address,
"DefaultIssuanceModule",
debtIssuanceMock.address
);

setToken = await setup.createSetToken(
[cComp.address],
[BigNumber.from(10000000000)],
[secondCompoundLeverageModule.address, setup.issuanceModule.address]
[secondCompoundLeverageModule.address, setup.issuanceModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
await gulpComptrollerMock.addSetTokenAddress(setToken.address);
// Initialize module if set to true
await secondCompoundLeverageModule.initialize(
Expand Down Expand Up @@ -2760,6 +2823,7 @@ describe("CompoundLeverageModule", () => {

describe("#addRegister", async () => {
let setToken: SetToken;
let otherIssuanceModule: DebtIssuanceMock;
let isInitialized: boolean;
let subjectSetToken: Address;
let subjectDebtIssuanceModule: Address;
Expand All @@ -2769,11 +2833,15 @@ describe("CompoundLeverageModule", () => {
});

beforeEach(async () => {
otherIssuanceModule = await deployer.mocks.deployDebtIssuanceMock();
await setup.controller.addModule(otherIssuanceModule.address);

setToken = await setup.createSetToken(
[cEther.address],
[BigNumber.from(10000000000)],
[compoundLeverageModule.address, setup.issuanceModule.address]
[compoundLeverageModule.address, setup.issuanceModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
// Initialize module if set to true
if (isInitialized) {
await compoundLeverageModule.initialize(
Expand All @@ -2784,22 +2852,22 @@ describe("CompoundLeverageModule", () => {
}
await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO);

// Add debt issuance mock after initializing Compound leverage module, so register is never called
await setToken.addModule(debtIssuanceMock.address);
await debtIssuanceMock.initialize(setToken.address);
// Add other issuance mock after initializing Compound leverage module, so register is never called
await setToken.addModule(otherIssuanceModule.address);
await otherIssuanceModule.initialize(setToken.address);

subjectSetToken = setToken.address;
subjectDebtIssuanceModule = debtIssuanceMock.address;
subjectDebtIssuanceModule = otherIssuanceModule.address;
});

async function subject(): Promise<any> {
return compoundLeverageModule.addRegister(subjectSetToken, subjectDebtIssuanceModule);
}

it("should register on the debt issuance module", async () => {
const previousIsRegistered = await debtIssuanceMock.isRegistered(setToken.address);
it("should register on the other issuance module", async () => {
const previousIsRegistered = await otherIssuanceModule.isRegistered(setToken.address);
await subject();
const currentIsRegistered = await debtIssuanceMock.isRegistered(setToken.address);
const currentIsRegistered = await otherIssuanceModule.isRegistered(setToken.address);
expect(previousIsRegistered).to.be.false;
expect(currentIsRegistered).to.be.true;
});
Expand Down Expand Up @@ -2837,7 +2905,7 @@ describe("CompoundLeverageModule", () => {

describe("when debt issuance module is not initialized on SetToken", async () => {
beforeEach(async () => {
await setToken.removeModule(debtIssuanceMock.address);
await setToken.removeModule(otherIssuanceModule.address);
});

it("should revert", async () => {
Expand All @@ -2862,8 +2930,9 @@ describe("CompoundLeverageModule", () => {
setToken = await setup.createSetToken(
[setup.weth.address, setup.dai.address],
[ether(1), ether(100)],
[compoundLeverageModule.address]
[compoundLeverageModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
// Initialize module if set to true
if (isInitialized) {
await compoundLeverageModule.initialize(
Expand Down Expand Up @@ -2998,8 +3067,9 @@ describe("CompoundLeverageModule", () => {
setToken = await setup.createSetToken(
[setup.weth.address, setup.dai.address],
[ether(1), ether(100)],
[compoundLeverageModule.address]
[compoundLeverageModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
// Initialize module if set to true
if (isInitialized) {
await compoundLeverageModule.initialize(
Expand Down Expand Up @@ -3136,8 +3206,9 @@ describe("CompoundLeverageModule", () => {
setToken = await setup.createSetToken(
[setup.weth.address, setup.dai.address],
[ether(1), ether(100)],
[compoundLeverageModule.address, setup.issuanceModule.address]
[compoundLeverageModule.address, setup.issuanceModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO);

// Initialize module if set to true
Expand Down Expand Up @@ -3256,8 +3327,9 @@ describe("CompoundLeverageModule", () => {
setToken = await setup.createSetToken(
[setup.weth.address, setup.dai.address],
[ether(1), ether(100)],
[compoundLeverageModule.address, setup.issuanceModule.address]
[compoundLeverageModule.address, setup.issuanceModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
await setup.issuanceModule.initialize(setToken.address, ADDRESS_ZERO);
// Initialize module if set to true
if (isInitialized) {
Expand Down Expand Up @@ -3376,8 +3448,9 @@ describe("CompoundLeverageModule", () => {
setToken = await setup.createSetToken(
[cEther.address, cDai.address],
[BigNumber.from(10000000000), BigNumber.from(100000000000)],
[compoundLeverageModule.address, setup.issuanceModule.address]
[compoundLeverageModule.address, setup.issuanceModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
// Initialize module if set to true
if (isInitialized) {
await compoundLeverageModule.initialize(
Expand Down Expand Up @@ -3567,8 +3640,9 @@ describe("CompoundLeverageModule", () => {
setToken = await setup.createSetToken(
[cEther.address, cDai.address],
[BigNumber.from(10000000000), BigNumber.from(100000000000)],
[compoundLeverageModule.address, setup.issuanceModule.address]
[compoundLeverageModule.address, setup.issuanceModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
// Initialize module if set to true
if (isInitialized) {
await compoundLeverageModule.initialize(
Expand Down Expand Up @@ -3761,8 +3835,9 @@ describe("CompoundLeverageModule", () => {
setToken = await setup.createSetToken(
[cEther.address],
[BigNumber.from(10000000000)],
[compoundLeverageModule.address, setup.issuanceModule.address]
[compoundLeverageModule.address, setup.issuanceModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
// Initialize module if set to true
if (isInitialized) {
await compoundLeverageModule.initialize(
Expand Down Expand Up @@ -3891,8 +3966,9 @@ describe("CompoundLeverageModule", () => {
setToken = await setup.createSetToken(
[cEther.address],
[BigNumber.from(10000000000)],
[compoundLeverageModule.address, setup.issuanceModule.address]
[compoundLeverageModule.address, setup.issuanceModule.address, debtIssuanceMock.address]
);
await debtIssuanceMock.initialize(setToken.address);
// Initialize module if set to true
if (isInitialized) {
await compoundLeverageModule.initialize(
Expand Down