Skip to content

Commit

Permalink
🐴 Add stability pool whitelist
Browse files Browse the repository at this point in the history
  • Loading branch information
nezouse committed May 6, 2024
1 parent 6c0c7ee commit d1cfd49
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 25 deletions.
1 change: 1 addition & 0 deletions contracts/Interfaces/IStabilityPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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 ---

Expand Down
10 changes: 10 additions & 0 deletions contracts/StabilityPool.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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);
}
Expand Down
5 changes: 4 additions & 1 deletion test/trinity/GasCompensationTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}

Expand Down
29 changes: 27 additions & 2 deletions test/trinity/StabilityPoolTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}

Expand Down Expand Up @@ -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 })
Expand Down Expand Up @@ -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 })
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1151,7 +1176,7 @@ contract("StabilityPool", async accounts => {
}) // 180 TRI closed
await stabilityPool.withdrawFromSP(dec(199_000, 18), validCollateral, { from: whale })
const stability_col_AfterWhaleERC20 = await stabilityPool.getCollateral(erc20.address)

const collateralId = unsortedCollaterals.indexOf(erc20.address)
const lastAssetError_Offset= (await stabilityPool.lastAssetError_Offset(collateralId)).div(toBN(10).pow(toBN(18)))
assert.closeTo(stability_col_AfterWhaleERC20.sub(aliceExpectedGainERC20), lastAssetError_Offset, toBN(Math.floor(lastAssetError_Offset * 0.001)))
Expand Down
10 changes: 6 additions & 4 deletions test/trinity/VesselManagerTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down Expand Up @@ -538,8 +540,8 @@ contract("VesselManager", async accounts => {

const L_ETH_expected_2_Asset = L_ETH_expected_1_Asset.add(
B_collateral_Asset.add(B_collateral_Asset.mul(L_ETH_expected_1_Asset).div(mv._1e18BN))
.mul(mv._1e18BN)
.div(A_collateral_Asset)
.mul(mv._1e18BN)
.div(A_collateral_Asset)
)
const L_TRIDebt_expected_2 = L_TRIDebt_expected_1_Asset.add(
B_totalDebt_Asset.add(B_increasedTotalDebt_Asset)
Expand Down
36 changes: 19 additions & 17 deletions test/trinity/VesselManager_RecoveryModeTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}

Expand Down Expand Up @@ -719,9 +721,9 @@ contract("VesselManager - in Recovery Mode", async accounts => {
assert.isAtMost(
th.getDifference(
L_ETH_Asset,
B_coll_Asset.sub(B_coll_Asset.mul(spDeposit).div(B_totalDebt_Asset))
.mul(mv._1e18BN)
.div(A_coll_Asset.add(D_coll_Asset))
B_coll_Asset.sub(B_coll_Asset.mul(spDeposit).div(B_totalDebt_Asset))
.mul(mv._1e18BN)
.div(A_coll_Asset.add(D_coll_Asset))
),
100
)
Expand Down Expand Up @@ -3404,9 +3406,9 @@ contract("VesselManager - in Recovery Mode", async accounts => {
th.assertIsApproximatelyEqual(liquidatedDebt_Asset, F_totalDebt_Asset.add(G_totalDebt_Asset))
th.assertIsApproximatelyEqual(
liquidatedColl_Asset,
F_totalDebt_Asset.add(G_totalDebt_Asset)
.mul(toBN(dec(11, 17)))
.div(price)
F_totalDebt_Asset.add(G_totalDebt_Asset)
.mul(toBN(dec(11, 17)))
.div(price)
)

// check collateral surplus
Expand Down Expand Up @@ -3540,9 +3542,9 @@ contract("VesselManager - in Recovery Mode", async accounts => {
th.assertIsApproximatelyEqual(liquidatedDebt_Asset, F_totalDebt_Asset.add(G_totalDebt_Asset))
th.assertIsApproximatelyEqual(
liquidatedColl_Asset,
F_totalDebt_Asset.add(G_totalDebt_Asset)
.mul(toBN(dec(11, 17)))
.div(price)
F_totalDebt_Asset.add(G_totalDebt_Asset)
.mul(toBN(dec(11, 17)))
.div(price)
)

// check collateral surplus
Expand Down Expand Up @@ -5935,9 +5937,9 @@ contract("VesselManager - in Recovery Mode", async accounts => {
th.assertIsApproximatelyEqual(liquidatedDebt_Asset, F_totalDebt_Asset.add(G_totalDebt_Asset))
th.assertIsApproximatelyEqual(
liquidatedColl_Asset,
F_totalDebt_Asset.add(G_totalDebt_Asset)
.mul(toBN(dec(11, 17)))
.div(price)
F_totalDebt_Asset.add(G_totalDebt_Asset)
.mul(toBN(dec(11, 17)))
.div(price)
)

// check collateral surplus
Expand Down Expand Up @@ -6078,9 +6080,9 @@ contract("VesselManager - in Recovery Mode", async accounts => {
th.assertIsApproximatelyEqual(liquidatedDebt_Asset, F_totalDebt_Asset.add(G_totalDebt_Asset))
th.assertIsApproximatelyEqual(
liquidatedColl_Asset,
F_totalDebt_Asset.add(G_totalDebt_Asset)
.mul(toBN(dec(11, 17)))
.div(price)
F_totalDebt_Asset.add(G_totalDebt_Asset)
.mul(toBN(dec(11, 17)))
.div(price)
)

// check collateral surplus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}

Expand Down

0 comments on commit d1cfd49

Please sign in to comment.