diff --git a/contracts/protocol/modules/AaveLeverageModule.sol b/contracts/protocol/modules/AaveLeverageModule.sol index 6d141c281..80d72c246 100644 --- a/contracts/protocol/modules/AaveLeverageModule.sol +++ b/contracts/protocol/modules/AaveLeverageModule.sol @@ -221,7 +221,10 @@ contract AaveLeverageModule is ModuleBase, ReentrancyGuard, Ownable, IModuleIssu ModuleBase(_controller) { lendingPoolAddressesProvider = _lendingPoolAddressesProvider; - IProtocolDataProvider _protocolDataProvider = IProtocolDataProvider(_lendingPoolAddressesProvider.getAddress(bytes32("0x1"))); + IProtocolDataProvider _protocolDataProvider = IProtocolDataProvider( + // Use the raw input vs bytes32() conversion. This is to ensure the input is an uint and not a string. + _lendingPoolAddressesProvider.getAddress(0x0100000000000000000000000000000000000000000000000000000000000000) + ); protocolDataProvider = _protocolDataProvider; IProtocolDataProvider.TokenData[] memory reserveTokens = _protocolDataProvider.getAllReservesTokens(); diff --git a/package.json b/package.json index 174f24133..0e42261dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@setprotocol/set-protocol-v2", - "version": "0.0.53", + "version": "0.0.54", "description": "", "main": "dist", "types": "dist/types", diff --git a/test/fixtures/aaveV2.spec.ts b/test/fixtures/aaveV2.spec.ts index 7abae8769..a9044764f 100644 --- a/test/fixtures/aaveV2.spec.ts +++ b/test/fixtures/aaveV2.spec.ts @@ -42,10 +42,12 @@ describe("AaveV2Fixture", async () => { const lendingPoolAddress = await addressProvider.getLendingPool(); const lendingPoolConfiuratorAddress = await addressProvider.getLendingPoolConfigurator(); const lendingPoolCollateralManager = await addressProvider.getLendingPoolCollateralManager(); + const protocolDataProvider = await addressProvider.getAddress("0x0100000000000000000000000000000000000000000000000000000000000000"); expect(lendingPoolAddress).to.eq(aaveSetup.lendingPool.address); expect(lendingPoolConfiuratorAddress).to.eq(aaveSetup.lendingPoolConfigurator.address); expect(lendingPoolCollateralManager).to.eq(aaveSetup.lendingPoolCollateralManager.address); + expect(protocolDataProvider).to.eq(aaveSetup.protocolDataProvider.address); }); it("should set initial asset prices and market rates", async () => { diff --git a/test/integration/deployments/aaveLeverageModuleDeployment.spec.ts b/test/integration/deployments/aaveLeverageModuleDeployment.spec.ts new file mode 100644 index 000000000..36a4aea09 --- /dev/null +++ b/test/integration/deployments/aaveLeverageModuleDeployment.spec.ts @@ -0,0 +1,101 @@ +import "module-alias/register"; + +import { Address } from "@utils/types"; +import { Account } from "@utils/test/types"; +import { + AaveV2, +} from "@utils/contracts"; +import { + AaveV2LendingPoolAddressesProvider, + AaveV2ProtocolDataProvider +} from "@utils/contracts/aaveV2"; +import DeployHelper from "@utils/deploys"; +import { + getAccounts, + getSystemFixture, + getWaffleExpect, + getAaveV2Fixture, +} from "@utils/test/index"; +import dependencies from "@utils/deploys/dependencies"; + +import { SystemFixture, AaveV2Fixture } from "@utils/fixtures"; + +const expect = getWaffleExpect(); + +describe("AaveLeverageModule Deployment Integration [ @forked-mainnet ]", () => { + let owner: Account; + + let deployer: DeployHelper; + + let setup: SystemFixture; + let aaveSetup: AaveV2Fixture; + + let aaveV2Library: AaveV2; + let lendingPoolAddressesProvider: AaveV2LendingPoolAddressesProvider; + let protocolDataProvider: AaveV2ProtocolDataProvider; + + before(async () => { + [ + owner, + ] = await getAccounts(); + + + deployer = new DeployHelper(owner.wallet); + setup = getSystemFixture(owner.address); + await setup.initialize(); + + aaveSetup = getAaveV2Fixture(owner.address); + + aaveV2Library = await deployer.libraries.deployAaveV2(); + lendingPoolAddressesProvider = aaveSetup.getForkedAaveLendingPoolAddressesProvider(); + protocolDataProvider = aaveSetup.getForkedAaveV2ProtocolDataProvider(); + }); + + describe("#constructor", function() { + context("when deploying the AaveLeverageModule with mainnet dependencies", async () => { + let subjectController: Address; + let subjectLendingPoolAddressesProvider: Address; + + beforeEach(async () => { + subjectController = setup.controller.address; + subjectLendingPoolAddressesProvider = lendingPoolAddressesProvider.address; + }); + + async function subject(): Promise { + return await deployer.modules.deployAaveLeverageModule( + subjectController, + subjectLendingPoolAddressesProvider, + "contracts/protocol/integration/lib/AaveV2.sol:AaveV2", + aaveV2Library.address, + ); + } + + it("should set the correct controller", async () => { + const aaveLeverageModule = await subject(); + + const controller = await aaveLeverageModule.controller(); + expect(controller).to.eq(subjectController); + }); + + it("should set the correct Aave contracts", async () => { + const aaveLeverageModule = await subject(); + + const returnedLendingPoolAddressesProvider = await aaveLeverageModule.lendingPoolAddressesProvider(); + const returnedProtocolDataProvider = await aaveLeverageModule.protocolDataProvider(); + + expect(returnedLendingPoolAddressesProvider).to.eq(dependencies.AAVE_LENDING_POOL_ADDRESSES_PROVIDER[1]); + expect(returnedProtocolDataProvider).to.eq(dependencies.AAVE_PROTOCOL_DATA_PROVIDER[1]); + }); + + it("should set the correct underlying to reserve tokens mappings (using a single asset USDC as our proxy)", async () => { + const aaveLeverageModule = await subject(); + + const returnedReserveTokens = await aaveLeverageModule.underlyingToReserveTokens(dependencies.USDC[1]); + const actualReserveTokens = await protocolDataProvider.getReserveTokensAddresses(dependencies.USDC[1]); + + expect(returnedReserveTokens.aToken).to.eq(actualReserveTokens.aTokenAddress); + expect(returnedReserveTokens.variableDebtToken).to.eq(actualReserveTokens.variableDebtTokenAddress); + }); + }); + }); +}); diff --git a/utils/deploys/dependencies.ts b/utils/deploys/dependencies.ts index 5763239f8..d93a0e673 100644 --- a/utils/deploys/dependencies.ts +++ b/utils/deploys/dependencies.ts @@ -66,6 +66,18 @@ export default { 42: "0x3d07e0780fd534759dbf1d7e3d92f454b783c4f4", }, + // AAVE V2 + + // Aave addresses https://docs.aave.com/developers/deployed-contracts/deployed-contracts + AAVE_LENDING_POOL_ADDRESSES_PROVIDER: { + 1: "0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5", + 42: "0x88757f2f99175387aB4C6a4b3067c77A695b0349", + }, + AAVE_PROTOCOL_DATA_PROVIDER: { + 1: "0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d", + 42: "0x3c73A5E5785cAC854D468F727c606C07488a29D6", + }, + // UNISWAP UNISWAP_FACTORY: { @@ -199,6 +211,8 @@ export const DEPENDENCY = { WETH: "WETH", // External Protocols + AAVE_LENDING_POOL_ADDRESSES_PROVIDER: "AAVE_LENDING_POOL_ADDRESSES_PROVIDER", + AAVE_PROTOCOL_DATA_PROVIDER: "AAVE_PROTOCOL_DATA_PROVIDER", UNISWAP_FACTORY: "UNISWAP_FACTORY", UNISWAP_ROUTER: "UNISWAP_ROUTER", WETH_DAI_UNI_PAIR: "WETH_DAI_UNI_PAIR", diff --git a/utils/deploys/deployExternal.ts b/utils/deploys/deployExternal.ts index 3b4d198d7..5982514d7 100644 --- a/utils/deploys/deployExternal.ts +++ b/utils/deploys/deployExternal.ts @@ -523,6 +523,14 @@ export default class DeployExternalContracts { ); } + public getForkedAaveLendingPoolAddressesProvider(_mainnetAddressesProvider: Address): AaveV2LendingPoolAddressesProvider { + return AaveV2LendingPoolAddressesProvider__factory.connect(_mainnetAddressesProvider, this._deployerSigner); + } + + public getForkedAaveV2ProtocolDataProvider(_mainnetAddressesProvider: Address): AaveV2ProtocolDataProvider { + return AaveV2ProtocolDataProvider__factory.connect(_mainnetAddressesProvider, this._deployerSigner); + } + // AAVE V2 LIBRARIES public async deployGeneralLogic(): Promise { return await new GenericLogic__factory(this._deployerSigner).deploy(); diff --git a/utils/fixtures/aaveV2Fixture.ts b/utils/fixtures/aaveV2Fixture.ts index bba19e3c8..780226efa 100644 --- a/utils/fixtures/aaveV2Fixture.ts +++ b/utils/fixtures/aaveV2Fixture.ts @@ -1,5 +1,5 @@ import DeployHelper from "../deploys"; -import { ethers , Signer } from "ethers"; +import { Signer } from "ethers"; import { JsonRpcProvider, Web3Provider } from "@ethersproject/providers"; import { Address } from "../types"; import { BigNumber, BigNumberish } from "@ethersproject/bignumber"; @@ -22,11 +22,9 @@ import { Executor, GovernanceStrategy } from "../contracts/aaveV2"; - - import { ether, getRandomAddress } from "../common"; - import { ADDRESS_ZERO, MAX_UINT_256 } from "../constants"; +import dependencies from "../deploys/dependencies"; export interface ReserveTokens { aToken: AaveV2AToken; @@ -107,7 +105,11 @@ export class AaveV2Fixture { await this.lendingPoolAddressesProvider.setLendingRateOracle(this.lendingRateOracle.address); await this.lendingPoolAddressesProvider.setPoolAdmin(await this._ownerSigner.getAddress()); await this.lendingPoolAddressesProvider.setLendingPoolCollateralManager(this.lendingPoolCollateralManager.address); - await this.lendingPoolAddressesProvider.setAddress(ethers.utils.formatBytes32String("0x1"), this.protocolDataProvider.address); + // Set the protocol data provider to the 0x1 ID. Use the raw input here vs converting to bytes32 to match Aave configuration + await this.lendingPoolAddressesProvider.setAddress( + "0x0100000000000000000000000000000000000000000000000000000000000000", + this.protocolDataProvider.address + ); // LendingPoolAddressProvider creates a new proxy contract and sets the passed in address as the implementation. // We then fetch the proxy's address and attach it to the contract object, which allows us to use the contract object @@ -236,6 +238,14 @@ export class AaveV2Fixture { this.lendingRateOracle.setMarketBorrowRate(asset, rate); } + public getForkedAaveLendingPoolAddressesProvider(): AaveV2LendingPoolAddressesProvider { + return this._deployer.external.getForkedAaveLendingPoolAddressesProvider(dependencies.AAVE_LENDING_POOL_ADDRESSES_PROVIDER[1]); + } + + public getForkedAaveV2ProtocolDataProvider(): AaveV2ProtocolDataProvider { + return this._deployer.external.getForkedAaveV2ProtocolDataProvider(dependencies.AAVE_PROTOCOL_DATA_PROVIDER[1]); + } + private async initializeGovernance(): Promise { // Deploy Executor