diff --git a/contracts/arbitrum/connectors/aave/v3/events.sol b/contracts/arbitrum/connectors/aave/v3/events.sol
new file mode 100644
index 00000000..9f60f22b
--- /dev/null
+++ b/contracts/arbitrum/connectors/aave/v3/events.sol
@@ -0,0 +1,33 @@
+pragma solidity ^0.7.0;
+
+contract Events {
+	event LogDeposit(
+		address indexed token,
+		uint256 tokenAmt,
+		uint256 getId,
+		uint256 setId
+	);
+	event LogWithdraw(
+		address indexed token,
+		uint256 tokenAmt,
+		uint256 getId,
+		uint256 setId
+	);
+	event LogBorrow(
+		address indexed token,
+		uint256 tokenAmt,
+		uint256 indexed rateMode,
+		uint256 getId,
+		uint256 setId
+	);
+	event LogPayback(
+		address indexed token,
+		uint256 tokenAmt,
+		uint256 indexed rateMode,
+		uint256 getId,
+		uint256 setId
+	);
+	event LogEnableCollateral(address[] tokens);
+	event LogSwapRateMode(address indexed token, uint256 rateMode);
+	event LogSetUserEMode(uint8 categoryId);
+}
diff --git a/contracts/arbitrum/connectors/aave/v3/helpers.sol b/contracts/arbitrum/connectors/aave/v3/helpers.sol
new file mode 100644
index 00000000..48dd4cdc
--- /dev/null
+++ b/contracts/arbitrum/connectors/aave/v3/helpers.sol
@@ -0,0 +1,66 @@
+pragma solidity ^0.7.0;
+
+import { DSMath } from "../../../common/math.sol";
+import { Basic } from "../../../common/basic.sol";
+import { AavePoolProviderInterface, AaveDataProviderInterface } from "./interface.sol";
+
+abstract contract Helpers is DSMath, Basic {
+	/**
+	 * @dev Aave Pool Provider
+	 */
+	AavePoolProviderInterface internal constant aaveProvider =
+		AavePoolProviderInterface(0x7B291364Ce799edd4CD471E5C023FF965347E1E1); // Arbitrum address - PoolAddressesProvider
+
+	/**
+	 * @dev Aave Pool Data Provider
+	 */
+	AaveDataProviderInterface internal constant aaveData =
+		AaveDataProviderInterface(0x224cD29570ED4Bfb2b55fF3eE27bEd28c58BBa86); //Arbitrum address - PoolDataProvider
+
+	/**
+	 * @dev Aave Referral Code
+	 */
+	uint16 internal constant referralCode = 3228;
+
+	/**
+	 * @dev Checks if collateral is enabled for an asset
+	 * @param token token address of the asset.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 */
+
+	function getIsColl(address token) internal view returns (bool isCol) {
+		(, , , , , , , , isCol) = aaveData.getUserReserveData(
+			token,
+			address(this)
+		);
+	}
+
+	/**
+	 * @dev Get total debt balance & fee for an asset
+	 * @param token token address of the debt.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param rateMode Borrow rate mode (Stable = 1, Variable = 2)
+	 */
+	function getPaybackBalance(address token, uint256 rateMode)
+		internal
+		view
+		returns (uint256)
+	{
+		(, uint256 stableDebt, uint256 variableDebt, , , , , , ) = aaveData
+			.getUserReserveData(token, address(this));
+		return rateMode == 1 ? stableDebt : variableDebt;
+	}
+
+	/**
+	 * @dev Get total collateral balance for an asset
+	 * @param token token address of the collateral.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 */
+	function getCollateralBalance(address token)
+		internal
+		view
+		returns (uint256 bal)
+	{
+		(bal, , , , , , , , ) = aaveData.getUserReserveData(
+			token,
+			address(this)
+		);
+	}
+}
diff --git a/contracts/arbitrum/connectors/aave/v3/interface.sol b/contracts/arbitrum/connectors/aave/v3/interface.sol
new file mode 100644
index 00000000..8ae14716
--- /dev/null
+++ b/contracts/arbitrum/connectors/aave/v3/interface.sol
@@ -0,0 +1,91 @@
+pragma solidity ^0.7.0;
+
+interface AaveInterface {
+	function supply(
+		address asset,
+		uint256 amount,
+		address onBehalfOf,
+		uint16 referralCode
+	) external;
+
+	function withdraw(
+		address asset,
+		uint256 amount,
+		address to
+	) external returns (uint256);
+
+	function borrow(
+		address asset,
+		uint256 amount,
+		uint256 interestRateMode,
+		uint16 referralCode,
+		address onBehalfOf
+	) external;
+
+	function repay(
+		address asset,
+		uint256 amount,
+		uint256 interestRateMode,
+		address onBehalfOf
+	) external returns (uint256);
+
+	function repayWithATokens(
+		address asset,
+		uint256 amount,
+		uint256 interestRateMode
+	) external returns (uint256);
+
+	function setUserUseReserveAsCollateral(address asset, bool useAsCollateral)
+		external;
+
+	function swapBorrowRateMode(address asset, uint256 interestRateMode)
+		external;
+
+	function setUserEMode(uint8 categoryId) external;
+}
+
+interface AavePoolProviderInterface {
+	function getPool() external view returns (address);
+}
+
+interface AaveDataProviderInterface {
+	function getReserveTokensAddresses(address _asset)
+		external
+		view
+		returns (
+			address aTokenAddress,
+			address stableDebtTokenAddress,
+			address variableDebtTokenAddress
+		);
+
+	function getUserReserveData(address _asset, address _user)
+		external
+		view
+		returns (
+			uint256 currentATokenBalance,
+			uint256 currentStableDebt,
+			uint256 currentVariableDebt,
+			uint256 principalStableDebt,
+			uint256 scaledVariableDebt,
+			uint256 stableBorrowRate,
+			uint256 liquidityRate,
+			uint40 stableRateLastUpdated,
+			bool usageAsCollateralEnabled
+		);
+
+	function getReserveEModeCategory(address asset)
+		external
+		view
+		returns (uint256);
+}
+
+interface AaveAddressProviderRegistryInterface {
+	function getAddressesProvidersList()
+		external
+		view
+		returns (address[] memory);
+}
+
+interface ATokenInterface {
+	function balanceOf(address _user) external view returns (uint256);
+}
diff --git a/contracts/arbitrum/connectors/aave/v3/main.sol b/contracts/arbitrum/connectors/aave/v3/main.sol
new file mode 100644
index 00000000..1004d0ec
--- /dev/null
+++ b/contracts/arbitrum/connectors/aave/v3/main.sol
@@ -0,0 +1,296 @@
+pragma solidity ^0.7.0;
+
+/**
+ * @title Aave v3.
+ * @dev Lending & Borrowing.
+ */
+
+import { TokenInterface } from "../../../common/interfaces.sol";
+import { Stores } from "../../../common/stores.sol";
+import { Helpers } from "./helpers.sol";
+import { Events } from "./events.sol";
+import { AaveInterface } from "./interface.sol";
+
+abstract contract AaveResolver is Events, Helpers {
+	/**
+	 * @dev Deposit ETH/ERC20_Token.
+	 * @notice Deposit a token to Aave v2 for lending / collaterization.
+	 * @param token The address of the token to deposit.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param amt The amount of the token to deposit. (For max: `uint256(-1)`)
+	 * @param getId ID to retrieve amt.
+	 * @param setId ID stores the amount of tokens deposited.
+	 */
+	function deposit(
+		address token,
+		uint256 amt,
+		uint256 getId,
+		uint256 setId
+	)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _amt = getUint(getId, amt);
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		bool isEth = token == ethAddr;
+		address _token = isEth ? wethAddr : token;
+
+		TokenInterface tokenContract = TokenInterface(_token);
+
+		if (isEth) {
+			_amt = _amt == uint256(-1) ? address(this).balance : _amt;
+			convertEthToWeth(isEth, tokenContract, _amt);
+		} else {
+			_amt = _amt == uint256(-1)
+				? tokenContract.balanceOf(address(this))
+				: _amt;
+		}
+
+		approve(tokenContract, address(aave), _amt);
+
+		aave.supply(_token, _amt, address(this), referralCode);
+
+		if (!getIsColl(_token)) {
+			aave.setUserUseReserveAsCollateral(_token, true);
+		}
+
+		setUint(setId, _amt);
+
+		_eventName = "LogDeposit(address,uint256,uint256,uint256)";
+		_eventParam = abi.encode(token, _amt, getId, setId);
+	}
+
+	/**
+	 * @dev Withdraw ETH/ERC20_Token.
+	 * @notice Withdraw deposited token from Aave v2
+	 * @param token The address of the token to withdraw.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`)
+	 * @param getId ID to retrieve amt.
+	 * @param setId ID stores the amount of tokens withdrawn.
+	 */
+	function withdraw(
+		address token,
+		uint256 amt,
+		uint256 getId,
+		uint256 setId
+	)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _amt = getUint(getId, amt);
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+		bool isEth = token == ethAddr;
+		address _token = isEth ? wethAddr : token;
+
+		TokenInterface tokenContract = TokenInterface(_token);
+
+		uint256 initialBal = tokenContract.balanceOf(address(this));
+		aave.withdraw(_token, _amt, address(this));
+		uint256 finalBal = tokenContract.balanceOf(address(this));
+
+		_amt = sub(finalBal, initialBal);
+
+		convertWethToEth(isEth, tokenContract, _amt);
+
+		setUint(setId, _amt);
+
+		_eventName = "LogWithdraw(address,uint256,uint256,uint256)";
+		_eventParam = abi.encode(token, _amt, getId, setId);
+	}
+
+	/**
+	 * @dev Borrow ETH/ERC20_Token.
+	 * @notice Borrow a token using Aave v2
+	 * @param token The address of the token to borrow.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param amt The amount of the token to borrow.
+	 * @param rateMode The type of borrow debt. (For Stable: 1, Variable: 2)
+	 * @param getId ID to retrieve amt.
+	 * @param setId ID stores the amount of tokens borrowed.
+	 */
+	function borrow(
+		address token,
+		uint256 amt,
+		uint256 rateMode,
+		uint256 getId,
+		uint256 setId
+	)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _amt = getUint(getId, amt);
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		bool isEth = token == ethAddr;
+		address _token = isEth ? wethAddr : token;
+
+		aave.borrow(_token, _amt, rateMode, referralCode, address(this));
+		convertWethToEth(isEth, TokenInterface(_token), _amt);
+
+		setUint(setId, _amt);
+
+		_eventName = "LogBorrow(address,uint256,uint256,uint256,uint256)";
+		_eventParam = abi.encode(token, _amt, rateMode, getId, setId);
+	}
+
+	/**
+	 * @dev Payback borrowed ETH/ERC20_Token.
+	 * @notice Payback debt owed.
+	 * @param token The address of the token to payback.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param amt The amount of the token to payback. (For max: `uint256(-1)`)
+	 * @param rateMode The type of debt paying back. (For Stable: 1, Variable: 2)
+	 * @param getId ID to retrieve amt.
+	 * @param setId ID stores the amount of tokens paid back.
+	 */
+	function payback(
+		address token,
+		uint256 amt,
+		uint256 rateMode,
+		uint256 getId,
+		uint256 setId
+	)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _amt = getUint(getId, amt);
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		bool isEth = token == ethAddr;
+		address _token = isEth ? wethAddr : token;
+
+		TokenInterface tokenContract = TokenInterface(_token);
+
+		_amt = _amt == uint256(-1) ? getPaybackBalance(_token, rateMode) : _amt;
+
+		if (isEth) convertEthToWeth(isEth, tokenContract, _amt);
+
+		approve(tokenContract, address(aave), _amt);
+
+		aave.repay(_token, _amt, rateMode, address(this));
+
+		setUint(setId, _amt);
+
+		_eventName = "LogPayback(address,uint256,uint256,uint256,uint256)";
+		_eventParam = abi.encode(token, _amt, rateMode, getId, setId);
+	}
+
+	/**
+	 * @dev Payback borrowed ETH/ERC20_Token using aTokens.
+	 * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the equivalent debt tokens.
+	 * @param token The address of the token to payback.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param amt The amount of the token to payback. (For max: `uint256(-1)`)
+	 * @param rateMode The type of debt paying back. (For Stable: 1, Variable: 2)
+	 * @param getId ID to retrieve amt.
+	 * @param setId ID stores the amount of tokens paid back.
+	 */
+	function paybackWithATokens(
+		address token,
+		uint256 amt,
+		uint256 rateMode,
+		uint256 getId,
+		uint256 setId
+	)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _amt = getUint(getId, amt);
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		bool isEth = token == ethAddr;
+		address _token = isEth ? wethAddr : token;
+
+		TokenInterface tokenContract = TokenInterface(_token);
+
+		_amt = _amt == uint256(-1) ? getPaybackBalance(_token, rateMode) : _amt;
+
+		if (isEth) convertEthToWeth(isEth, tokenContract, _amt);
+
+		approve(tokenContract, address(aave), _amt);
+
+		aave.repayWithATokens(_token, _amt, rateMode);
+
+		setUint(setId, _amt);
+
+		_eventName = "LogPayback(address,uint256,uint256,uint256,uint256)";
+		_eventParam = abi.encode(token, _amt, rateMode, getId, setId);
+	}
+
+	/**
+	 * @dev Enable collateral
+	 * @notice Enable an array of tokens as collateral
+	 * @param tokens Array of tokens to enable collateral
+	 */
+	function enableCollateral(address[] calldata tokens)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _length = tokens.length;
+		require(_length > 0, "0-tokens-not-allowed");
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		for (uint256 i = 0; i < _length; i++) {
+			address token = tokens[i];
+			if (getCollateralBalance(token) > 0 && !getIsColl(token)) {
+				aave.setUserUseReserveAsCollateral(token, true);
+			}
+		}
+
+		_eventName = "LogEnableCollateral(address[])";
+		_eventParam = abi.encode(tokens);
+	}
+
+	/**
+	 * @dev Swap borrow rate mode
+	 * @notice Swaps user borrow rate mode between variable and stable
+	 * @param token The address of the token to swap borrow rate.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param rateMode Desired borrow rate mode. (Stable = 1, Variable = 2)
+	 */
+	function swapBorrowRateMode(address token, uint256 rateMode)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		uint256 currentRateMode = rateMode == 1 ? 2 : 1;
+
+		if (getPaybackBalance(token, currentRateMode) > 0) {
+			aave.swapBorrowRateMode(token, rateMode);
+		}
+
+		_eventName = "LogSwapRateMode(address,uint256)";
+		_eventParam = abi.encode(token, rateMode);
+	}
+
+	/**
+	 * @dev Set user e-mode
+	 * @notice Updates the user's e-mode category
+	 * @param categoryId The category Id of the e-mode user want to set
+	 */
+	function setUserEMode(uint8 categoryId)
+		external
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		aave.setUserEMode(categoryId);
+
+		_eventName = "LogSetUserEMode(uint8)";
+		_eventParam = abi.encode(categoryId);
+	}
+}
+
+contract ConnectV2AaveV3Arbitrum is AaveResolver {
+	string public constant name = "AaveV3-v1.0";
+}
diff --git a/contracts/avalanche/connectors/aave/v3/helpers.sol b/contracts/avalanche/connectors/aave/v3/helpers.sol
index 13431d11..171d7ac5 100644
--- a/contracts/avalanche/connectors/aave/v3/helpers.sol
+++ b/contracts/avalanche/connectors/aave/v3/helpers.sol
@@ -9,13 +9,13 @@ abstract contract Helpers is DSMath, Basic {
 	 * @dev Aave Pool Provider
 	 */
 	AavePoolProviderInterface internal constant aaveProvider =
-		AavePoolProviderInterface(0xA55125A90d75a95EC00130E8E8C197dB5641Eb19); // rinkeby address
+		AavePoolProviderInterface(0x7013523049CeC8b06F594edb8c5fb7F232c0Df7C); // Avalanche address - PoolAddressesProvider
 
 	/**
 	 * @dev Aave Pool Data Provider
 	 */
 	AaveDataProviderInterface internal constant aaveData =
-		AaveDataProviderInterface(0x256bBbeDbA70a1240a1EB64210abB1b063267408); // rinkeby address
+		AaveDataProviderInterface(0x44C7324E9d84D6534DD6f292Cc08f1816e45Ff6e); // Avalanche address - PoolDataProvider
 
 	/**
 	 * @dev Aave Referral Code
diff --git a/contracts/avalanche/connectors/aave/v3/main.sol b/contracts/avalanche/connectors/aave/v3/main.sol
index 14d5596f..6697810a 100644
--- a/contracts/avalanche/connectors/aave/v3/main.sol
+++ b/contracts/avalanche/connectors/aave/v3/main.sol
@@ -291,6 +291,6 @@ abstract contract AaveResolver is Events, Helpers {
 	}
 }
 
-contract ConnectV2AaveV3Polygon is AaveResolver {
+contract ConnectV2AaveV3Avalanche is AaveResolver {
 	string public constant name = "AaveV3-v1.0";
 }
diff --git a/contracts/optimism/connectors/aave/v3/events.sol b/contracts/optimism/connectors/aave/v3/events.sol
new file mode 100644
index 00000000..9f60f22b
--- /dev/null
+++ b/contracts/optimism/connectors/aave/v3/events.sol
@@ -0,0 +1,33 @@
+pragma solidity ^0.7.0;
+
+contract Events {
+	event LogDeposit(
+		address indexed token,
+		uint256 tokenAmt,
+		uint256 getId,
+		uint256 setId
+	);
+	event LogWithdraw(
+		address indexed token,
+		uint256 tokenAmt,
+		uint256 getId,
+		uint256 setId
+	);
+	event LogBorrow(
+		address indexed token,
+		uint256 tokenAmt,
+		uint256 indexed rateMode,
+		uint256 getId,
+		uint256 setId
+	);
+	event LogPayback(
+		address indexed token,
+		uint256 tokenAmt,
+		uint256 indexed rateMode,
+		uint256 getId,
+		uint256 setId
+	);
+	event LogEnableCollateral(address[] tokens);
+	event LogSwapRateMode(address indexed token, uint256 rateMode);
+	event LogSetUserEMode(uint8 categoryId);
+}
diff --git a/contracts/optimism/connectors/aave/v3/helpers.sol b/contracts/optimism/connectors/aave/v3/helpers.sol
new file mode 100644
index 00000000..fc896b79
--- /dev/null
+++ b/contracts/optimism/connectors/aave/v3/helpers.sol
@@ -0,0 +1,66 @@
+pragma solidity ^0.7.0;
+
+import { DSMath } from "../../../common/math.sol";
+import { Basic } from "../../../common/basic.sol";
+import { AavePoolProviderInterface, AaveDataProviderInterface } from "./interface.sol";
+
+abstract contract Helpers is DSMath, Basic {
+	/**
+	 * @dev Aave Pool Provider
+	 */
+	AavePoolProviderInterface internal constant aaveProvider =
+		AavePoolProviderInterface(0x7013523049CeC8b06F594edb8c5fb7F232c0Df7C); // Optimism address - PoolAddressesProvider
+
+	/**
+	 * @dev Aave Pool Data Provider
+	 */
+	AaveDataProviderInterface internal constant aaveData =
+		AaveDataProviderInterface(0x44C7324E9d84D6534DD6f292Cc08f1816e45Ff6e); // Optimism address - PoolDataProvider
+
+	/**
+	 * @dev Aave Referral Code
+	 */
+	uint16 internal constant referralCode = 3228;
+
+	/**
+	 * @dev Checks if collateral is enabled for an asset
+	 * @param token token address of the asset.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 */
+
+	function getIsColl(address token) internal view returns (bool isCol) {
+		(, , , , , , , , isCol) = aaveData.getUserReserveData(
+			token,
+			address(this)
+		);
+	}
+
+	/**
+	 * @dev Get total debt balance & fee for an asset
+	 * @param token token address of the debt.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param rateMode Borrow rate mode (Stable = 1, Variable = 2)
+	 */
+	function getPaybackBalance(address token, uint256 rateMode)
+		internal
+		view
+		returns (uint256)
+	{
+		(, uint256 stableDebt, uint256 variableDebt, , , , , , ) = aaveData
+			.getUserReserveData(token, address(this));
+		return rateMode == 1 ? stableDebt : variableDebt;
+	}
+
+	/**
+	 * @dev Get total collateral balance for an asset
+	 * @param token token address of the collateral.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 */
+	function getCollateralBalance(address token)
+		internal
+		view
+		returns (uint256 bal)
+	{
+		(bal, , , , , , , , ) = aaveData.getUserReserveData(
+			token,
+			address(this)
+		);
+	}
+}
diff --git a/contracts/optimism/connectors/aave/v3/interface.sol b/contracts/optimism/connectors/aave/v3/interface.sol
new file mode 100644
index 00000000..8ae14716
--- /dev/null
+++ b/contracts/optimism/connectors/aave/v3/interface.sol
@@ -0,0 +1,91 @@
+pragma solidity ^0.7.0;
+
+interface AaveInterface {
+	function supply(
+		address asset,
+		uint256 amount,
+		address onBehalfOf,
+		uint16 referralCode
+	) external;
+
+	function withdraw(
+		address asset,
+		uint256 amount,
+		address to
+	) external returns (uint256);
+
+	function borrow(
+		address asset,
+		uint256 amount,
+		uint256 interestRateMode,
+		uint16 referralCode,
+		address onBehalfOf
+	) external;
+
+	function repay(
+		address asset,
+		uint256 amount,
+		uint256 interestRateMode,
+		address onBehalfOf
+	) external returns (uint256);
+
+	function repayWithATokens(
+		address asset,
+		uint256 amount,
+		uint256 interestRateMode
+	) external returns (uint256);
+
+	function setUserUseReserveAsCollateral(address asset, bool useAsCollateral)
+		external;
+
+	function swapBorrowRateMode(address asset, uint256 interestRateMode)
+		external;
+
+	function setUserEMode(uint8 categoryId) external;
+}
+
+interface AavePoolProviderInterface {
+	function getPool() external view returns (address);
+}
+
+interface AaveDataProviderInterface {
+	function getReserveTokensAddresses(address _asset)
+		external
+		view
+		returns (
+			address aTokenAddress,
+			address stableDebtTokenAddress,
+			address variableDebtTokenAddress
+		);
+
+	function getUserReserveData(address _asset, address _user)
+		external
+		view
+		returns (
+			uint256 currentATokenBalance,
+			uint256 currentStableDebt,
+			uint256 currentVariableDebt,
+			uint256 principalStableDebt,
+			uint256 scaledVariableDebt,
+			uint256 stableBorrowRate,
+			uint256 liquidityRate,
+			uint40 stableRateLastUpdated,
+			bool usageAsCollateralEnabled
+		);
+
+	function getReserveEModeCategory(address asset)
+		external
+		view
+		returns (uint256);
+}
+
+interface AaveAddressProviderRegistryInterface {
+	function getAddressesProvidersList()
+		external
+		view
+		returns (address[] memory);
+}
+
+interface ATokenInterface {
+	function balanceOf(address _user) external view returns (uint256);
+}
diff --git a/contracts/optimism/connectors/aave/v3/main.sol b/contracts/optimism/connectors/aave/v3/main.sol
new file mode 100644
index 00000000..d778832b
--- /dev/null
+++ b/contracts/optimism/connectors/aave/v3/main.sol
@@ -0,0 +1,296 @@
+pragma solidity ^0.7.0;
+
+/**
+ * @title Aave v3.
+ * @dev Lending & Borrowing.
+ */
+
+import { TokenInterface } from "../../../common/interfaces.sol";
+import { Stores } from "../../../common/stores.sol";
+import { Helpers } from "./helpers.sol";
+import { Events } from "./events.sol";
+import { AaveInterface } from "./interface.sol";
+
+abstract contract AaveResolver is Events, Helpers {
+	/**
+	 * @dev Deposit ETH/ERC20_Token.
+	 * @notice Deposit a token to Aave v2 for lending / collaterization.
+	 * @param token The address of the token to deposit.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param amt The amount of the token to deposit. (For max: `uint256(-1)`)
+	 * @param getId ID to retrieve amt.
+	 * @param setId ID stores the amount of tokens deposited.
+	 */
+	function deposit(
+		address token,
+		uint256 amt,
+		uint256 getId,
+		uint256 setId
+	)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _amt = getUint(getId, amt);
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		bool isEth = token == ethAddr;
+		address _token = isEth ? wethAddr : token;
+
+		TokenInterface tokenContract = TokenInterface(_token);
+
+		if (isEth) {
+			_amt = _amt == uint256(-1) ? address(this).balance : _amt;
+			convertEthToWeth(isEth, tokenContract, _amt);
+		} else {
+			_amt = _amt == uint256(-1)
+				? tokenContract.balanceOf(address(this))
+				: _amt;
+		}
+
+		approve(tokenContract, address(aave), _amt);
+
+		aave.supply(_token, _amt, address(this), referralCode);
+
+		if (!getIsColl(_token)) {
+			aave.setUserUseReserveAsCollateral(_token, true);
+		}
+
+		setUint(setId, _amt);
+
+		_eventName = "LogDeposit(address,uint256,uint256,uint256)";
+		_eventParam = abi.encode(token, _amt, getId, setId);
+	}
+
+	/**
+	 * @dev Withdraw ETH/ERC20_Token.
+	 * @notice Withdraw deposited token from Aave v2
+	 * @param token The address of the token to withdraw.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param amt The amount of the token to withdraw. (For max: `uint256(-1)`)
+	 * @param getId ID to retrieve amt.
+	 * @param setId ID stores the amount of tokens withdrawn.
+	 */
+	function withdraw(
+		address token,
+		uint256 amt,
+		uint256 getId,
+		uint256 setId
+	)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _amt = getUint(getId, amt);
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+		bool isEth = token == ethAddr;
+		address _token = isEth ? wethAddr : token;
+
+		TokenInterface tokenContract = TokenInterface(_token);
+
+		uint256 initialBal = tokenContract.balanceOf(address(this));
+		aave.withdraw(_token, _amt, address(this));
+		uint256 finalBal = tokenContract.balanceOf(address(this));
+
+		_amt = sub(finalBal, initialBal);
+
+		convertWethToEth(isEth, tokenContract, _amt);
+
+		setUint(setId, _amt);
+
+		_eventName = "LogWithdraw(address,uint256,uint256,uint256)";
+		_eventParam = abi.encode(token, _amt, getId, setId);
+	}
+
+	/**
+	 * @dev Borrow ETH/ERC20_Token.
+	 * @notice Borrow a token using Aave v2
+	 * @param token The address of the token to borrow.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param amt The amount of the token to borrow.
+	 * @param rateMode The type of borrow debt. (For Stable: 1, Variable: 2)
+	 * @param getId ID to retrieve amt.
+	 * @param setId ID stores the amount of tokens borrowed.
+	 */
+	function borrow(
+		address token,
+		uint256 amt,
+		uint256 rateMode,
+		uint256 getId,
+		uint256 setId
+	)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _amt = getUint(getId, amt);
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		bool isEth = token == ethAddr;
+		address _token = isEth ? wethAddr : token;
+
+		aave.borrow(_token, _amt, rateMode, referralCode, address(this));
+		convertWethToEth(isEth, TokenInterface(_token), _amt);
+
+		setUint(setId, _amt);
+
+		_eventName = "LogBorrow(address,uint256,uint256,uint256,uint256)";
+		_eventParam = abi.encode(token, _amt, rateMode, getId, setId);
+	}
+
+	/**
+	 * @dev Payback borrowed ETH/ERC20_Token.
+	 * @notice Payback debt owed.
+	 * @param token The address of the token to payback.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param amt The amount of the token to payback. (For max: `uint256(-1)`)
+	 * @param rateMode The type of debt paying back. (For Stable: 1, Variable: 2)
+	 * @param getId ID to retrieve amt.
+	 * @param setId ID stores the amount of tokens paid back.
+	 */
+	function payback(
+		address token,
+		uint256 amt,
+		uint256 rateMode,
+		uint256 getId,
+		uint256 setId
+	)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _amt = getUint(getId, amt);
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		bool isEth = token == ethAddr;
+		address _token = isEth ? wethAddr : token;
+
+		TokenInterface tokenContract = TokenInterface(_token);
+
+		_amt = _amt == uint256(-1) ? getPaybackBalance(_token, rateMode) : _amt;
+
+		if (isEth) convertEthToWeth(isEth, tokenContract, _amt);
+
+		approve(tokenContract, address(aave), _amt);
+
+		aave.repay(_token, _amt, rateMode, address(this));
+
+		setUint(setId, _amt);
+
+		_eventName = "LogPayback(address,uint256,uint256,uint256,uint256)";
+		_eventParam = abi.encode(token, _amt, rateMode, getId, setId);
+	}
+
+	/**
+	 * @dev Payback borrowed ETH/ERC20_Token using aTokens.
+	 * @notice Repays a borrowed `amount` on a specific reserve using the reserve aTokens, burning the equivalent debt tokens.
+	 * @param token The address of the token to payback.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param amt The amount of the token to payback. (For max: `uint256(-1)`)
+	 * @param rateMode The type of debt paying back. (For Stable: 1, Variable: 2)
+	 * @param getId ID to retrieve amt.
+	 * @param setId ID stores the amount of tokens paid back.
+	 */
+	function paybackWithATokens(
+		address token,
+		uint256 amt,
+		uint256 rateMode,
+		uint256 getId,
+		uint256 setId
+	)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _amt = getUint(getId, amt);
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		bool isEth = token == ethAddr;
+		address _token = isEth ? wethAddr : token;
+
+		TokenInterface tokenContract = TokenInterface(_token);
+
+		_amt = _amt == uint256(-1) ? getPaybackBalance(_token, rateMode) : _amt;
+
+		if (isEth) convertEthToWeth(isEth, tokenContract, _amt);
+
+		approve(tokenContract, address(aave), _amt);
+
+		aave.repayWithATokens(_token, _amt, rateMode);
+
+		setUint(setId, _amt);
+
+		_eventName = "LogPayback(address,uint256,uint256,uint256,uint256)";
+		_eventParam = abi.encode(token, _amt, rateMode, getId, setId);
+	}
+
+	/**
+	 * @dev Enable collateral
+	 * @notice Enable an array of tokens as collateral
+	 * @param tokens Array of tokens to enable collateral
+	 */
+	function enableCollateral(address[] calldata tokens)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		uint256 _length = tokens.length;
+		require(_length > 0, "0-tokens-not-allowed");
+
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		for (uint256 i = 0; i < _length; i++) {
+			address token = tokens[i];
+			if (getCollateralBalance(token) > 0 && !getIsColl(token)) {
+				aave.setUserUseReserveAsCollateral(token, true);
+			}
+		}
+
+		_eventName = "LogEnableCollateral(address[])";
+		_eventParam = abi.encode(tokens);
+	}
+
+	/**
+	 * @dev Swap borrow rate mode
+	 * @notice Swaps user borrow rate mode between variable and stable
+	 * @param token The address of the token to swap borrow rate.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+	 * @param rateMode Desired borrow rate mode. (Stable = 1, Variable = 2)
+	 */
+	function swapBorrowRateMode(address token, uint256 rateMode)
+		external
+		payable
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		uint256 currentRateMode = rateMode == 1 ? 2 : 1;
+
+		if (getPaybackBalance(token, currentRateMode) > 0) {
+			aave.swapBorrowRateMode(token, rateMode);
+		}
+
+		_eventName = "LogSwapRateMode(address,uint256)";
+		_eventParam = abi.encode(token, rateMode);
+	}
+
+	/**
+	 * @dev Set user e-mode
+	 * @notice Updates the user's e-mode category
+	 * @param categoryId The category Id of the e-mode user want to set
+	 */
+	function setUserEMode(uint8 categoryId)
+		external
+		returns (string memory _eventName, bytes memory _eventParam)
+	{
+		AaveInterface aave = AaveInterface(aaveProvider.getPool());
+
+		aave.setUserEMode(categoryId);
+
+		_eventName = "LogSetUserEMode(uint8)";
+		_eventParam = abi.encode(categoryId);
+	}
+}
+
+contract ConnectV2AaveV3Optimism is AaveResolver {
+	string public constant name = "AaveV3-v1.0";
+}
diff --git a/contracts/polygon/connectors/aave/v3/helpers.sol b/contracts/polygon/connectors/aave/v3/helpers.sol
index 13431d11..8b2d0c50 100644
--- a/contracts/polygon/connectors/aave/v3/helpers.sol
+++ b/contracts/polygon/connectors/aave/v3/helpers.sol
@@ -9,13 +9,13 @@ abstract contract Helpers is DSMath, Basic {
 	 * @dev Aave Pool Provider
 	 */
 	AavePoolProviderInterface internal constant aaveProvider =
-		AavePoolProviderInterface(0xA55125A90d75a95EC00130E8E8C197dB5641Eb19); // rinkeby address
+		AavePoolProviderInterface(0x7013523049CeC8b06F594edb8c5fb7F232c0Df7C); // Polygon address - PoolAddressesProvider
 
 	/**
 	 * @dev Aave Pool Data Provider
 	 */
 	AaveDataProviderInterface internal constant aaveData =
-		AaveDataProviderInterface(0x256bBbeDbA70a1240a1EB64210abB1b063267408); // rinkeby address
+		AaveDataProviderInterface(0x44C7324E9d84D6534DD6f292Cc08f1816e45Ff6e); // Polygon address - PoolDataProvider
 
 	/**
 	 * @dev Aave Referral Code