From cb1b11a3c8686db04eaa3d479d29d4b4cdf1e0d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Stankiewicz?= Date: Mon, 6 May 2024 15:30:18 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=B4=20Add=20stability=20pool=20whiteli?= =?UTF-8?q?st=20(#13)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/Interfaces/IStabilityPool.sol | 1 + contracts/StabilityPool.sol | 10 +++++++ test/trinity/GasCompensationTest.js | 5 +++- test/trinity/StabilityPoolTest.js | 27 ++++++++++++++++++- test/trinity/VesselManagerTest.js | 6 +++-- .../trinity/VesselManager_RecoveryModeTest.js | 6 +++-- ...nager_RecoveryMode_BatchLiquidationTest.js | 5 +++- 7 files changed, 53 insertions(+), 7 deletions(-) diff --git a/contracts/Interfaces/IStabilityPool.sol b/contracts/Interfaces/IStabilityPool.sol index a056882..e7585da 100644 --- a/contracts/Interfaces/IStabilityPool.sol +++ b/contracts/Interfaces/IStabilityPool.sol @@ -38,6 +38,7 @@ interface IStabilityPool is IDeposit { error StabilityPool__AdminContractOnly(address sender, address expected); error StabilityPool__VesselManagerOnly(address sender, address expected); error StabilityPool__ArrayNotInAscendingOrder(); + error StabilityPool__AddressNotCollateralWhitelisted(address _address); // --- Functions --- diff --git a/contracts/StabilityPool.sol b/contracts/StabilityPool.sol index db4ae0d..2885497 100644 --- a/contracts/StabilityPool.sol +++ b/contracts/StabilityPool.sol @@ -255,6 +255,11 @@ contract StabilityPool is ReentrancyGuardUpgradeable, UUPSUpgradeable, TrinityBa * Skipping a collateral forfeits the available rewards (can be useful for gas optimizations) */ function provideToSP(uint256 _amount, address[] calldata _assets) external override nonReentrant { + for(uint256 i = 0; i < _assets.length; i++) { + if(!IAdminContract(adminContract).getIsAddressCollateralWhitelisted(_assets[i], msg.sender)) { + revert StabilityPool__AddressNotCollateralWhitelisted(_assets[i]); + } + } _requireNonZeroAmount(_amount); uint256 initialDeposit = deposits[msg.sender]; @@ -281,6 +286,11 @@ contract StabilityPool is ReentrancyGuardUpgradeable, UUPSUpgradeable, TrinityBa */ function withdrawFromSP(uint256 _amount, address[] calldata _assets) external { + for(uint256 i = 0; i < _assets.length; i++) { + if(!IAdminContract(adminContract).getIsAddressCollateralWhitelisted(_assets[i], msg.sender)) { + revert StabilityPool__AddressNotCollateralWhitelisted(_assets[i]); + } + } (address[] memory assets, uint256[] memory amounts) = _withdrawFromSP(_amount, _assets); _sendGainsToDepositor(msg.sender, assets, amounts); } diff --git a/test/trinity/GasCompensationTest.js b/test/trinity/GasCompensationTest.js index fea240a..af487e8 100644 --- a/test/trinity/GasCompensationTest.js +++ b/test/trinity/GasCompensationTest.js @@ -33,8 +33,11 @@ const deploy = async (treasury, distributor, mintingAccounts) => { validCollateral = await adminContract.getValidCollateral() - for(const account of mintingAccounts) { + for (const account of mintingAccounts) { await adminContract.setLiquidatorWhitelisted(account, true) + for (const collateral of validCollateral) { + await adminContract.setAddressCollateralWhitelisted(collateral, account, true) + } } } diff --git a/test/trinity/StabilityPoolTest.js b/test/trinity/StabilityPoolTest.js index ac9f26d..554f560 100644 --- a/test/trinity/StabilityPoolTest.js +++ b/test/trinity/StabilityPoolTest.js @@ -38,8 +38,11 @@ const deploy = async (treasury, distributor, mintingAccounts) => { // getDepositorGains() expects a sorted collateral array validCollateral = validCollateral.slice(0).sort((a, b) => toBN(a.toLowerCase()).sub(toBN(b.toLowerCase()))) - for(const account of mintingAccounts) { + for (const account of mintingAccounts) { await adminContract.setLiquidatorWhitelisted(account, true) + for (const collateral of validCollateral) { + await adminContract.setAddressCollateralWhitelisted(collateral, account, true) + } } } @@ -125,6 +128,16 @@ contract("StabilityPool", async accounts => { }) describe("Providing", async () => { + it("provideToSp(): reverts if not whitelisted", async () => { + try { + await stabilityPool.provideToSP(200, [alice], { from: alice }) + assert.isFalse(tx.receipt.status) + } catch (err) { + assert.include(err.message, "revert") + assert.include(err.message, `StabilityPool__AddressNotCollateralWhitelisted("${alice}")`) + } + }) + it("provideToSP(): increases the Stability Pool balance", async () => { await _openVessel(erc20, (extraDebtTokenAmt = 200), alice) await stabilityPool.provideToSP(200, validCollateral, { from: alice }) @@ -740,6 +753,8 @@ contract("StabilityPool", async accounts => { it("provideToSP(): passing wrong address to asset list has no impact", async () => { await openWhaleVessel(erc20, (icr = 10), (extraDebtTokenAmt = 1_000_000)) // first call won't revert as there is no initial deposit + await adminContract.setAddressCollateralWhitelisted(alice, whale, true) + await stabilityPool.provideToSP(dec(199_000, 18), [alice], { from: whale }) await stabilityPool.provideToSP(dec(1_000, 18), [alice], { from: whale }) await stabilityPool.withdrawFromSP(dec(1_000, 18), [alice], { from: whale }) @@ -767,6 +782,16 @@ contract("StabilityPool", async accounts => { }) describe("Withdrawing", async () => { + it("withdrawFromSP(): reverts if not whitelisted", async () => { + try { + await stabilityPool.withdrawFromSP(200, [alice], { from: alice }) + assert.isFalse(tx.receipt.status) + } catch (err) { + assert.include(err.message, "revert") + assert.include(err.message, `StabilityPool__AddressNotCollateralWhitelisted("${alice}")`) + } + }) + it("withdrawFromSP(): reverts when user has no active deposit", async () => { await _openVessel(erc20, 100, alice) await _openVessel(erc20, 100, bob) diff --git a/test/trinity/VesselManagerTest.js b/test/trinity/VesselManagerTest.js index 0d34086..fac9bc9 100644 --- a/test/trinity/VesselManagerTest.js +++ b/test/trinity/VesselManagerTest.js @@ -47,8 +47,10 @@ const deploy = async (treasury, distributor, mintingAccounts) => { // getDepositorGains() expects a sorted collateral array validCollateral = validCollateral.slice(0).sort((a, b) => toBN(a.toLowerCase()).sub(toBN(b.toLowerCase()))) - for(const account of mintingAccounts) { - await adminContract.setAddressCollateralWhitelisted(erc20.address, account, true) + for (const account of mintingAccounts) { + for (const collateral of validCollateral) { + await adminContract.setAddressCollateralWhitelisted(collateral, account, true) + } await adminContract.setLiquidatorWhitelisted(account, true) } } diff --git a/test/trinity/VesselManager_RecoveryModeTest.js b/test/trinity/VesselManager_RecoveryModeTest.js index 8e1b83e..0af8ee7 100644 --- a/test/trinity/VesselManager_RecoveryModeTest.js +++ b/test/trinity/VesselManager_RecoveryModeTest.js @@ -43,9 +43,11 @@ const deploy = async (treasury, distributor, mintingAccounts) => { // getDepositorGains() expects a sorted collateral array validCollateral = validCollateral.slice(0).sort((a, b) => toBN(a.toLowerCase()).sub(toBN(b.toLowerCase()))) - for(const account of mintingAccounts) { - await adminContract.setAddressCollateralWhitelisted(erc20.address, account, true) + for (const account of mintingAccounts) { await adminContract.setLiquidatorWhitelisted(account, true) + for (const collateral of validCollateral) { + await adminContract.setAddressCollateralWhitelisted(collateral, account, true) + } } } diff --git a/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js b/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js index 6f03fdf..c0c9e00 100644 --- a/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js +++ b/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js @@ -40,8 +40,11 @@ const deploy = async (treasury, distributor, mintingAccounts) => { // getDepositorGains() expects a sorted collateral array validCollateral = validCollateral.slice(0).sort((a, b) => toBN(a.toLowerCase()).sub(toBN(b.toLowerCase()))) - for(const account of mintingAccounts) { + for (const account of mintingAccounts) { await adminContract.setLiquidatorWhitelisted(account, true) + for (const collateral of validCollateral) { + await adminContract.setAddressCollateralWhitelisted(collateral, account, true) + } } }