Skip to content

Commit 86a2e59

Browse files
committed
Update config for liquidity pool
1 parent 66d8703 commit 86a2e59

File tree

5 files changed

+145
-35
lines changed

5 files changed

+145
-35
lines changed

contracts/LiquidityPoolAave.sol

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ contract LiquidityPoolAave is LiquidityPool {
4141
error NothingToRepay();
4242
error CollateralNotSupported();
4343
error CannotWithdrawAToken();
44+
error InvalidLength();
4445

4546
event SuppliedToAave(uint256 amount);
4647
event BorrowTokenLTVSet(address token, uint256 oldLTV, uint256 newLTV);
@@ -83,10 +84,18 @@ contract LiquidityPoolAave is LiquidityPool {
8384

8485
// Admin functions
8586

86-
function setBorrowTokenLTV(address token, uint256 ltv) external onlyRole(DEFAULT_ADMIN_ROLE) {
87-
uint256 oldLTV = _borrowTokenLTV[token];
88-
_borrowTokenLTV[token] = ltv;
89-
emit BorrowTokenLTVSet(token, oldLTV, ltv);
87+
function setBorrowTokenLTVs(
88+
address[] calldata tokens,
89+
uint256[] calldata ltvs
90+
) external onlyRole(DEFAULT_ADMIN_ROLE) {
91+
require(tokens.length == ltvs.length, InvalidLength());
92+
for (uint256 i = 0; i < tokens.length; ++i) {
93+
address token = tokens[i];
94+
uint256 ltv = ltvs[i];
95+
uint256 oldLTV = _borrowTokenLTV[token];
96+
_borrowTokenLTV[token] = ltv;
97+
emit BorrowTokenLTVSet(token, oldLTV, ltv);
98+
}
9099
}
91100

92101
function setDefaultLTV(uint256 defaultLTV_) external onlyRole(DEFAULT_ADMIN_ROLE) {

hardhat.config.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,23 @@ task("set-default-ltv", "Update Liquidity Pool config")
4444
console.log(`Default LTV set to ${ltv} on ${targetAddress}.`);
4545
});
4646

47-
task("set-token-ltv", "Update Liquidity Pool config")
48-
.addParam("token", "Token to update LTV for")
47+
task("set-token-ltvs", "Update Liquidity Pool config")
48+
.addParam("tokens", "Comma separated list of tokens to update LTV for")
49+
.addParam("ltvs", "Comma separated list of new LTV values")
4950
.addOptionalParam("pool", "Liquidity Pool proxy address or id", "LiquidityPoolAaveUSDC", types.string)
50-
.addOptionalParam("ltv", "New LTV value", 20n * 10n**16n, types.bigint)
51-
.setAction(async ({token, pool, ltv}: {token: string, pool: string, ltv: bigint}, hre) => {
51+
.setAction(async (args: {tokens: string, ltvs: string, pool: string}, hre) => {
5252
const {resolveXAddress} = await loadTestHelpers();
5353
const [admin] = await hre.ethers.getSigners();
5454

55-
const targetAddress = await resolveXAddress(pool);
55+
const targetAddress = await resolveXAddress(args.pool);
5656
const target = (await hre.ethers.getContractAt("LiquidityPoolAave", targetAddress, admin)) as LiquidityPoolAave;
5757

58-
await target.setBorrowTokenLTV(token, ltv);
59-
console.log(`Token ${token} LTV set to ${ltv} on ${targetAddress}.`);
58+
const tokens = args.tokens && args.tokens.split(",") || [];
59+
const ltvs = args.ltvs && args.ltvs.split(",") || [];
60+
61+
await target.setBorrowTokenLTVs(tokens, ltvs);
62+
console.log(`Following tokens LTVs set on ${targetAddress}:`);
63+
console.table({tokens, ltvs});
6064
});
6165

6266
task("set-min-health-factor", "Update Liquidity Pool config")

network.config.ts

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@ interface RoutesConfig {
3434
Providers: Provider[];
3535
}
3636

37-
interface TokenLtv {
38-
token: string;
39-
LTV: number;
37+
interface TokenLtvConfig {
38+
Tokens: string[];
39+
LTVs: number[];
4040
}
4141

4242
interface AavePoolConfig {
4343
AaveAddressesProvider: string;
4444
minHealthFactor: number;
4545
defaultLTV: number;
46-
tokenLTVs?: TokenLtv[];
46+
tokenLTVs?: TokenLtvConfig;
4747
}
4848

4949
export interface NetworkConfig {
@@ -54,12 +54,12 @@ export interface NetworkConfig {
5454
IsTest: boolean;
5555
IsHub: boolean;
5656
AssetsLimit?: number;
57-
Admin?: string;
58-
AssetsAdjuster?: string;
59-
WithdrawProfit?: string;
60-
Pauser?: string;
61-
RebalanceCaller?: string;
62-
MpcAddress?: string;
57+
Admin: string;
58+
AssetsAdjuster: string;
59+
WithdrawProfit: string;
60+
Pauser: string;
61+
RebalanceCaller: string;
62+
MpcAddress: string;
6363
AavePool?: AavePoolConfig;
6464
USDCPool?: boolean;
6565
};
@@ -78,6 +78,12 @@ export const networkConfig: NetworksConfig = {
7878
USDC: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
7979
IsTest: false,
8080
IsHub: false,
81+
Admin: "",
82+
AssetsAdjuster: "",
83+
WithdrawProfit: "",
84+
Pauser: "",
85+
RebalanceCaller: "",
86+
MpcAddress: "",
8187
Routes: {
8288
Pools: [LiquidityPoolAaveUSDC],
8389
Domains: [Network.BASE],
@@ -98,6 +104,12 @@ export const networkConfig: NetworksConfig = {
98104
USDC: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
99105
IsTest: false,
100106
IsHub: false,
107+
Admin: "",
108+
AssetsAdjuster: "",
109+
WithdrawProfit: "",
110+
Pauser: "",
111+
RebalanceCaller: "",
112+
MpcAddress: "",
101113
AavePool: {
102114
AaveAddressesProvider: AAVEPools.AaveV3Avalanche.POOL_ADDRESSES_PROVIDER,
103115
minHealthFactor: 500,
@@ -113,6 +125,12 @@ export const networkConfig: NetworksConfig = {
113125
USDC: "0x0b2c639c533813f4aa9d7837caf62653d097ff85",
114126
IsTest: false,
115127
IsHub: false,
128+
Admin: "",
129+
AssetsAdjuster: "",
130+
WithdrawProfit: "",
131+
Pauser: "",
132+
RebalanceCaller: "",
133+
MpcAddress: "",
116134
AavePool: {
117135
AaveAddressesProvider: AAVEPools.AaveV3Optimism.POOL_ADDRESSES_PROVIDER,
118136
minHealthFactor: 500,
@@ -128,6 +146,12 @@ export const networkConfig: NetworksConfig = {
128146
USDC: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
129147
IsTest: false,
130148
IsHub: false,
149+
Admin: "",
150+
AssetsAdjuster: "",
151+
WithdrawProfit: "",
152+
Pauser: "",
153+
RebalanceCaller: "",
154+
MpcAddress: "",
131155
AavePool: {
132156
AaveAddressesProvider: AAVEPools.AaveV3Arbitrum.POOL_ADDRESSES_PROVIDER,
133157
minHealthFactor: 500,
@@ -143,6 +167,12 @@ export const networkConfig: NetworksConfig = {
143167
USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
144168
IsTest: false,
145169
IsHub: true,
170+
Admin: "",
171+
AssetsAdjuster: "",
172+
WithdrawProfit: "",
173+
Pauser: "",
174+
RebalanceCaller: "",
175+
MpcAddress: "",
146176
Routes: {
147177
Pools: [LiquidityPoolAaveUSDC],
148178
Domains: [Network.ETHEREUM],
@@ -163,6 +193,12 @@ export const networkConfig: NetworksConfig = {
163193
USDC: "0x3c499c542cef5e3811e1192ce70d8cc03d5c3359",
164194
IsTest: false,
165195
IsHub: false,
196+
Admin: "",
197+
AssetsAdjuster: "",
198+
WithdrawProfit: "",
199+
Pauser: "",
200+
RebalanceCaller: "",
201+
MpcAddress: "",
166202
AavePool: {
167203
AaveAddressesProvider: AAVEPools.AaveV3Polygon.POOL_ADDRESSES_PROVIDER,
168204
minHealthFactor: 500,
@@ -178,6 +214,12 @@ export const networkConfig: NetworksConfig = {
178214
USDC: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
179215
IsTest: true,
180216
IsHub: false,
217+
Admin: "",
218+
AssetsAdjuster: "",
219+
WithdrawProfit: "0xed24c1ca7c8d01c4ba862c6792ad6144f01566f2",
220+
Pauser: "0xcc5dd1eec29dbe028e61e91db5da4d453be48d90",
221+
RebalanceCaller: "0x20ad9b208767e98dba19346f88b2686f00dbcf58",
222+
MpcAddress: "0xc731bac6c62ecb49dba1393700218d03beaa0359",
181223
Routes: {
182224
Pools: [LiquidityPoolAaveUSDC, LiquidityPoolUSDC, LiquidityPoolUSDC],
183225
Domains: [Network.BASE_SEPOLIA, Network.ARBITRUM_SEPOLIA, Network.BASE_SEPOLIA],
@@ -194,6 +236,12 @@ export const networkConfig: NetworksConfig = {
194236
USDC: "0x5425890298aed601595a70ab815c96711a31bc65",
195237
IsTest: true,
196238
IsHub: false,
239+
Admin: "",
240+
AssetsAdjuster: "",
241+
WithdrawProfit: "0xed24c1ca7c8d01c4ba862c6792ad6144f01566f2",
242+
Pauser: "0xcc5dd1eec29dbe028e61e91db5da4d453be48d90",
243+
RebalanceCaller: "0x20ad9b208767e98dba19346f88b2686f00dbcf58",
244+
MpcAddress: "0xc731bac6c62ecb49dba1393700218d03beaa0359",
197245
AavePool: {
198246
AaveAddressesProvider: AAVEPools.AaveV3Fuji.POOL_ADDRESSES_PROVIDER,
199247
minHealthFactor: 500,
@@ -209,6 +257,12 @@ export const networkConfig: NetworksConfig = {
209257
USDC: "0x5fd84259d66Cd46123540766Be93DFE6D43130D7",
210258
IsTest: true,
211259
IsHub: false,
260+
Admin: "",
261+
AssetsAdjuster: "",
262+
WithdrawProfit: "0xed24c1ca7c8d01c4ba862c6792ad6144f01566f2",
263+
Pauser: "0xcc5dd1eec29dbe028e61e91db5da4d453be48d90",
264+
RebalanceCaller: "0x20ad9b208767e98dba19346f88b2686f00dbcf58",
265+
MpcAddress: "0xc731bac6c62ecb49dba1393700218d03beaa0359",
212266
AavePool: {
213267
AaveAddressesProvider: AAVEPools.AaveV3OptimismSepolia.POOL_ADDRESSES_PROVIDER,
214268
minHealthFactor: 500,
@@ -224,6 +278,12 @@ export const networkConfig: NetworksConfig = {
224278
USDC: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
225279
IsTest: true,
226280
IsHub: false,
281+
Admin: "",
282+
AssetsAdjuster: "",
283+
WithdrawProfit: "0xed24c1ca7c8d01c4ba862c6792ad6144f01566f2",
284+
Pauser: "0xcc5dd1eec29dbe028e61e91db5da4d453be48d90",
285+
RebalanceCaller: "0x20ad9b208767e98dba19346f88b2686f00dbcf58",
286+
MpcAddress: "0xc731bac6c62ecb49dba1393700218d03beaa0359",
227287
Routes: {
228288
Pools: [LiquidityPoolAaveUSDC, LiquidityPoolUSDC, LiquidityPoolUSDC],
229289
Domains: [Network.BASE_SEPOLIA, Network.ETHEREUM_SEPOLIA, Network.BASE_SEPOLIA],
@@ -244,6 +304,12 @@ export const networkConfig: NetworksConfig = {
244304
USDC: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
245305
IsTest: true,
246306
IsHub: true,
307+
Admin: "",
308+
AssetsAdjuster: "",
309+
WithdrawProfit: "0xed24c1ca7c8d01c4ba862c6792ad6144f01566f2",
310+
Pauser: "0xcc5dd1eec29dbe028e61e91db5da4d453be48d90",
311+
RebalanceCaller: "0x20ad9b208767e98dba19346f88b2686f00dbcf58",
312+
MpcAddress: "0xc731bac6c62ecb49dba1393700218d03beaa0359",
247313
Routes: {
248314
Pools: [LiquidityPoolUSDC, LiquidityPoolAaveUSDC],
249315
Domains: [Network.ETHEREUM_SEPOLIA, Network.ARBITRUM_SEPOLIA],
@@ -265,5 +331,11 @@ export const networkConfig: NetworksConfig = {
265331
USDC: "0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582",
266332
IsTest: true,
267333
IsHub: false,
334+
Admin: "",
335+
AssetsAdjuster: "",
336+
WithdrawProfit: "0xed24c1ca7c8d01c4ba862c6792ad6144f01566f2",
337+
Pauser: "0xcc5dd1eec29dbe028e61e91db5da4d453be48d90",
338+
RebalanceCaller: "0x20ad9b208767e98dba19346f88b2686f00dbcf58",
339+
MpcAddress: "0xc731bac6c62ecb49dba1393700218d03beaa0359",
268340
},
269341
};

scripts/deploy.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import dotenv from "dotenv";
22
dotenv.config();
33
import hre from "hardhat";
4-
import {MaxUint256, getBigInt, resolveAddress} from "ethers";
4+
import {MaxUint256, getBigInt} from "ethers";
55
import {toBytes32} from "../test/helpers";
66
import {
77
getVerifier, deployProxyX,
@@ -12,7 +12,7 @@ import {
1212
import {
1313
TestUSDC, SprinterUSDCLPShare, LiquidityHub,
1414
SprinterLiquidityMining, TestCCTPTokenMessenger, TestCCTPMessageTransmitter,
15-
Rebalancer, LiquidityPool,
15+
Rebalancer, LiquidityPool, LiquidityPoolAave
1616
} from "../typechain-types";
1717
import {
1818
networkConfig, Network, Provider, NetworkConfig, LiquidityPoolUSDC,
@@ -69,7 +69,7 @@ export async function main() {
6969
};
7070
}
7171

72-
assert(typeof config.AavePool !== 'undefined' || (typeof config.USDCPool !== 'undefined' && config.USDCPool),
72+
assert(typeof config.AavePool !== "undefined" || (typeof config.USDCPool !== "undefined" && config.USDCPool),
7373
"At least one pool should be present.")
7474

7575
if (!config.Routes) {
@@ -125,7 +125,7 @@ export async function main() {
125125
defaultLTV = defaultLTV * 10n ** 18n / 100n;
126126
}
127127

128-
let aavePool: LiquidityPool;
128+
let aavePool: LiquidityPoolAave;
129129
let mainPoolId: string;
130130
if (config.AavePool) {
131131
console.log("Deploying AAVE Liquidity Pool");
@@ -143,7 +143,11 @@ export async function main() {
143143
defaultLTV,
144144
],
145145
mainPoolId,
146-
)) as LiquidityPool;
146+
)) as LiquidityPoolAave;
147+
148+
if (config.AavePool.tokenLTVs) {
149+
await aavePool.setBorrowTokenLTVs(config.AavePool.tokenLTVs.Tokens, config.AavePool.tokenLTVs.LTVs)
150+
}
147151
console.log(`LiquidityPoolAave: ${aavePool.target}`);
148152

149153
config.Routes.Pools.push(await aavePool.getAddress());
@@ -257,8 +261,10 @@ export async function main() {
257261
}
258262

259263
if (deployer.address !== config.Admin) {
260-
await liquidityPool.grantRole(DEFAULT_ADMIN_ROLE, config.Admin);
261-
await liquidityPool.renounceRole(DEFAULT_ADMIN_ROLE, deployer);
264+
if (config.AavePool) {
265+
await aavePool!.grantRole(DEFAULT_ADMIN_ROLE, config.Admin);
266+
await aavePool!.renounceRole(DEFAULT_ADMIN_ROLE, deployer);
267+
}
262268

263269
if (config.USDCPool) {
264270
await usdcPool!.grantRole(DEFAULT_ADMIN_ROLE, config.Admin);

test/LiquidityPoolAave.ts

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,17 @@ describe("LiquidityPoolAave", function () {
13401340
await expect(liquidityPool.connect(user).withdrawProfit([uni.target], user.address))
13411341
.to.be.revertedWithCustomError(liquidityPool, "AccessControlUnauthorizedAccount");
13421342
});
1343+
1344+
it("Should NOT set token LTVs if array lengths don't match", async function () {
1345+
const {liquidityPool, admin, uni} = await loadFixture(deployAll);
1346+
const uni_ltv = 1000;
1347+
const rpl_ltv = 2000;
1348+
await expect(liquidityPool.connect(admin).setBorrowTokenLTVs(
1349+
[uni.target],
1350+
[uni_ltv, rpl_ltv]
1351+
))
1352+
.to.be.revertedWithCustomError(liquidityPool, "InvalidLength");
1353+
});
13431354
});
13441355

13451356
describe("Roles and admin functions", function () {
@@ -1376,19 +1387,27 @@ describe("LiquidityPoolAave", function () {
13761387
});
13771388

13781389
it("Should allow admin to set token LTV for each token", async function () {
1379-
const {liquidityPool, admin, uni} = await loadFixture(deployAll);
1380-
const oldLTV = await liquidityPool._borrowTokenLTV(uni.target);
1381-
const ltv = 1000;
1382-
await expect(liquidityPool.connect(admin).setBorrowTokenLTV(uni.target, ltv))
1383-
.to.emit(liquidityPool, "BorrowTokenLTVSet").withArgs(uni.target, oldLTV, ltv);
1390+
const {liquidityPool, admin, uni, rpl} = await loadFixture(deployAll);
1391+
const oldUniLTV = await liquidityPool._borrowTokenLTV(uni.target);
1392+
const oldRplLTV = await liquidityPool._borrowTokenLTV(rpl.target);
1393+
const uni_ltv = 1000;
1394+
const rpl_ltv = 2000;
1395+
await expect(liquidityPool.connect(admin).setBorrowTokenLTVs(
1396+
[uni.target, rpl.target],
1397+
[uni_ltv, rpl_ltv]
1398+
))
1399+
.to.emit(liquidityPool, "BorrowTokenLTVSet").withArgs(uni.target, oldUniLTV, uni_ltv)
1400+
.and.to.emit(liquidityPool, "BorrowTokenLTVSet").withArgs(rpl.target, oldRplLTV, rpl_ltv);
13841401
expect(await liquidityPool._borrowTokenLTV(uni.target))
1385-
.to.eq(ltv);
1402+
.to.eq(uni_ltv);
1403+
expect(await liquidityPool._borrowTokenLTV(rpl.target))
1404+
.to.eq(rpl_ltv);
13861405
});
13871406

13881407
it("Should NOT allow others to set token LTV for each token", async function () {
13891408
const {liquidityPool, user, uni} = await loadFixture(deployAll);
13901409
const ltv = 1000;
1391-
await expect(liquidityPool.connect(user).setBorrowTokenLTV(uni.target, ltv))
1410+
await expect(liquidityPool.connect(user).setBorrowTokenLTVs([uni.target], [ltv]))
13921411
.to.be.revertedWithCustomError(liquidityPool, "AccessControlUnauthorizedAccount");
13931412
});
13941413

0 commit comments

Comments
 (0)