From 08a74a1d6ade2a5537e9081c9dc10094a9097bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Stankiewicz?= Date: Mon, 29 Apr 2024 15:58:37 +0200 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9B=8F=EF=B8=8F=20Split=20debt=20and=20r?= =?UTF-8?q?edemption=20fees=20(#5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ⛏️ Split debt and redemption fees * Split treasury and distributor addresses --- contracts/BorrowerOperations.sol | 2 +- .../Dependencies/AddressesConfigurable.sol | 22 ++--- contracts/Dependencies/AddressesMainnet.sol | 1 + test/trinity/AccessControlTest.js | 8 +- test/trinity/AdminContractTest.js | 8 +- test/trinity/BorrowerOperationsTest.js | 88 +++++++++---------- test/trinity/BorrowerOperations_FeesTest.js | 36 ++++---- test/trinity/CollSurplusPoolTest.js | 8 +- test/trinity/ConnectContractsTest.js | 6 +- test/trinity/DebtTokenTest.js | 4 +- test/trinity/ERC20PermitTest.js | 4 +- test/trinity/GasCompensationTest.js | 8 +- test/trinity/HintHelpers_getApproxHintTest.js | 6 +- test/trinity/PoolsTest.js | 8 +- test/trinity/PriceFeedTest.js | 4 +- test/trinity/SortedVesselsTest.js | 10 +-- test/trinity/StabilityPoolTest.js | 7 +- test/trinity/VesselManagerTest.js | 7 +- .../VesselManager_LiquidationRewardsTest.js | 8 +- .../trinity/VesselManager_RecoveryModeTest.js | 7 +- ...nager_RecoveryMode_BatchLiquidationTest.js | 8 +- test/utils/deploymentHelpers.js | 7 +- 22 files changed, 137 insertions(+), 130 deletions(-) diff --git a/contracts/BorrowerOperations.sol b/contracts/BorrowerOperations.sol index 0602c85..975064d 100644 --- a/contracts/BorrowerOperations.sol +++ b/contracts/BorrowerOperations.sol @@ -334,7 +334,7 @@ contract BorrowerOperations is TrinityBase, ReentrancyGuardUpgradeable, UUPSUpgr function _triggerBorrowingFee(address _asset, address _borrower, uint256 _debtTokenAmount) internal returns (uint256) { uint256 debtTokenFee = IVesselManager(vesselManager).getBorrowingFee(_asset, _debtTokenAmount); - IDebtToken(debtToken).mint(_asset, treasuryAddress, debtTokenFee); + IDebtToken(debtToken).mint(_asset, distributorAddress, debtTokenFee); _updateVesselEpoch(_asset, _borrower); emit BorrowingFeePaid(_asset, _borrower, debtTokenFee); return debtTokenFee; diff --git a/contracts/Dependencies/AddressesConfigurable.sol b/contracts/Dependencies/AddressesConfigurable.sol index 8ec423a..ba26ac6 100644 --- a/contracts/Dependencies/AddressesConfigurable.sol +++ b/contracts/Dependencies/AddressesConfigurable.sol @@ -11,6 +11,7 @@ abstract contract AddressesConfigurable is OwnableUpgradeable { address public collSurplusPool; address public debtToken; address public defaultPool; + address public distributorAddress; address public gasPoolAddress; address public priceFeed; address public sortedVessels; @@ -33,8 +34,8 @@ abstract contract AddressesConfigurable is OwnableUpgradeable { function setAddresses(address[] calldata _addresses) external onlyOwner { require(!isAddressSetupInitialized, "Setup is already initialized"); - require(_addresses.length == 14, "Expected 14 addresses at setup"); - for (uint i = 0; i < 14; i++) { + require(_addresses.length == 15, "Expected 15 addresses at setup"); + for (uint i = 0; i < 15; i++) { require(_addresses[i] != address(0), "Invalid address"); } activePool = _addresses[0]; @@ -43,14 +44,15 @@ abstract contract AddressesConfigurable is OwnableUpgradeable { collSurplusPool = _addresses[3]; debtToken = _addresses[4]; defaultPool = _addresses[5]; - gasPoolAddress = _addresses[6]; - priceFeed = _addresses[7]; - sortedVessels = _addresses[8]; - stabilityPool = _addresses[9]; - timelockAddress = _addresses[10]; - treasuryAddress = _addresses[11]; - vesselManager = _addresses[12]; - vesselManagerOperations = _addresses[13]; + distributorAddress = _addresses[6]; + gasPoolAddress = _addresses[7]; + priceFeed = _addresses[8]; + sortedVessels = _addresses[9]; + stabilityPool = _addresses[10]; + timelockAddress = _addresses[11]; + treasuryAddress = _addresses[12]; + vesselManager = _addresses[13]; + vesselManagerOperations = _addresses[14]; isAddressSetupInitialized = true; } diff --git a/contracts/Dependencies/AddressesMainnet.sol b/contracts/Dependencies/AddressesMainnet.sol index 686d222..c2d7f70 100644 --- a/contracts/Dependencies/AddressesMainnet.sol +++ b/contracts/Dependencies/AddressesMainnet.sol @@ -9,6 +9,7 @@ abstract contract AddressesMainnet { address public constant collSurplusPool = 0x09dfdF392a56E4316e97A13e20b09C415fCD3d7b; address public constant debtToken = 0x15f74458aE0bFdAA1a96CA1aa779D715Cc1Eefe4; address public constant defaultPool = 0x84446698694B348EaeCE187b55df06AB4Ce72b35; + address public constant distributorAddress = 0x6F8Fe995422c5efE6487A7B07f67E84aaD9D4eC8; address public constant gasPoolAddress = 0x40E0e274A42D9b1a9D4B64dC6c46D21228d45C20; address public constant priceFeed = 0x89F1ecCF2644902344db02788A790551Bb070351; address public constant sortedVessels = 0xF31D88232F36098096d1eB69f0de48B53a1d18Ce; diff --git a/test/trinity/AccessControlTest.js b/test/trinity/AccessControlTest.js index 6bbac85..6a49128 100644 --- a/test/trinity/AccessControlTest.js +++ b/test/trinity/AccessControlTest.js @@ -9,8 +9,8 @@ var snapshotId var initialSnapshotId const openVessel = async params => th.openVessel(contracts.core, params) -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -31,10 +31,10 @@ const deploy = async (treasury, mintingAccounts) => { } contract("Access Control: functions where the caller is restricted to Trinity contract(s)", async accounts => { - const [alice, bob, treasury] = accounts + const [alice, bob, treasury, distributor] = accounts before(async () => { - await deploy(treasury, accounts.slice(0, 10)) + await deploy(treasury, distributor, accounts.slice(0, 10)) for (account of accounts.slice(0, 10)) { await openVessel({ asset: erc20.address, diff --git a/test/trinity/AdminContractTest.js b/test/trinity/AdminContractTest.js index 14201a1..0b562f1 100644 --- a/test/trinity/AdminContractTest.js +++ b/test/trinity/AdminContractTest.js @@ -8,8 +8,8 @@ var snapshotId var initialSnapshotId const openVessel = async params => th.openVessel(contracts.core, params) -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -30,7 +30,7 @@ const deploy = async (treasury, mintingAccounts) => { } contract("AdminContract", async accounts => { - const [owner, user, A, C, B, treasury] = accounts + const [owner, user, A, C, B, treasury, distributor] = accounts let BORROWING_FEE let CCR @@ -59,7 +59,7 @@ contract("AdminContract", async accounts => { const REDEMPTION_FEE_FLOOR_SAFETY_MIN = toBN('0') // 0% before(async () => { - await deploy(treasury, accounts.slice(0, 5)) + await deploy(treasury, distributor, accounts.slice(0, 5)) BORROWING_FEE = await adminContract.BORROWING_FEE_DEFAULT() CCR = await adminContract.CCR_DEFAULT() diff --git a/test/trinity/BorrowerOperationsTest.js b/test/trinity/BorrowerOperationsTest.js index 656e0d6..dbf73eb 100644 --- a/test/trinity/BorrowerOperationsTest.js +++ b/test/trinity/BorrowerOperationsTest.js @@ -21,8 +21,8 @@ var snapshotId var initialSnapshotId const openVessel = async params => th.openVessel(contracts.core, params) -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -43,7 +43,7 @@ const deploy = async (treasury, mintingAccounts) => { } contract("BorrowerOperations", async accounts => { - const [owner, alice, bob, carol, dennis, whale, A, B, C, D, E, multisig, treasury] = accounts + const [owner, alice, bob, carol, dennis, whale, A, B, C, D, E, multisig, treasury, distributor] = accounts const getOpenVesselTRIAmount = async (totalDebt, asset) => th.getOpenVesselTRIAmount(contracts.core, totalDebt, asset) @@ -59,7 +59,7 @@ contract("BorrowerOperations", async accounts => { describe("BorrowerOperations Mechanisms", async () => { before(async () => { - await deploy(treasury, []) + await deploy(treasury, distributor, []) MIN_NET_DEBT_ERC20 = await adminContract.getMinNetDebt(erc20.address) BORROWING_FEE_ERC20 = await adminContract.getBorrowingFee(erc20.address) @@ -1395,12 +1395,12 @@ contract("BorrowerOperations", async accounts => { assert.isTrue(baseRate_2_Asset.lt(baseRate_1_Asset)) }) */ - it("withdrawDebtTokens(): borrowing at non-zero base rate sends fee to treasury contract", async () => { + it("withdrawDebtTokens(): borrowing at non-zero base rate sends fee to distributor contract", async () => { // time fast-forwards 1 year await th.fastForwardTime(timeValues.SECONDS_IN_ONE_YEAR, web3.currentProvider) - const Treasury_TRIBalance_Before = await debtToken.balanceOf(treasury) - assert.equal(Treasury_TRIBalance_Before, "0") + const Distributor_TRIBalance_Before = await debtToken.balanceOf(distributor) + assert.equal(Distributor_TRIBalance_Before, "0") await openVessel({ asset: erc20.address, @@ -1449,8 +1449,8 @@ contract("BorrowerOperations", async accounts => { from: D, }) - const Treasury_TRIBalance_After = await debtToken.balanceOf(treasury) - assert.isTrue(Treasury_TRIBalance_After.gt(Treasury_TRIBalance_Before)) + const Distributor_TRIBalance_After = await debtToken.balanceOf(distributor) + assert.isTrue(Distributor_TRIBalance_After.gt(Distributor_TRIBalance_Before)) }) if (!withProxy) { @@ -1524,8 +1524,8 @@ contract("BorrowerOperations", async accounts => { // time fast-forwards 1 year await th.fastForwardTime(timeValues.SECONDS_IN_ONE_YEAR, web3.currentProvider) - const Treasury_TRIBalance_Before = await debtToken.balanceOf(treasury) - assert.equal(Treasury_TRIBalance_Before, "0") + const Distributor_TRIBalance_Before = await debtToken.balanceOf(distributor) + assert.equal(Distributor_TRIBalance_Before, "0") await openVessel({ asset: erc20.address, @@ -1576,8 +1576,8 @@ contract("BorrowerOperations", async accounts => { from: D, }) - let Treasury_TRIBalance_After = await debtToken.balanceOf(treasury) - assert.isTrue(Treasury_TRIBalance_After.gt(Treasury_TRIBalance_Before)) + let Distributor_TRIBalance_After = await debtToken.balanceOf(distributor) + assert.isTrue(Distributor_TRIBalance_After.gt(Distributor_TRIBalance_Before)) // Check D's TRI balance now equals their initial balance plus request TRI let D_TRIBalanceAfter = await debtToken.balanceOf(D) @@ -1589,8 +1589,8 @@ contract("BorrowerOperations", async accounts => { from: D, }) - Treasury_TRIBalance_After = await debtToken.balanceOf(treasury) - assert.isTrue(Treasury_TRIBalance_After.gt(Treasury_TRIBalance_Before)) + Distributor_TRIBalance_After = await debtToken.balanceOf(distributor) + assert.isTrue(Distributor_TRIBalance_After.gt(Distributor_TRIBalance_Before)) D_TRIBalanceAfter = await debtToken.balanceOf(D) assert.isTrue(D_TRIBalanceAfter.eq(D_TRIBalanceBefore.add(D_TRIRequest))) @@ -2616,12 +2616,12 @@ contract("BorrowerOperations", async accounts => { assert.isTrue(baseRate_2.lt(baseRate_1)) }) */ - it("adjustVessel(): borrowing at non-zero base rate sends TRI fee to treasury contract", async () => { + it("adjustVessel(): borrowing at non-zero base rate sends TRI fee to distributor contract", async () => { // time fast-forwards 1 year await th.fastForwardTime(timeValues.SECONDS_IN_ONE_YEAR, web3.currentProvider) - const Treasury_TRIBalance_Before = await debtToken.balanceOf(treasury) - assert.equal(Treasury_TRIBalance_Before, "0") + const Distributor_TRIBalance_Before = await debtToken.balanceOf(distributor) + assert.equal(Distributor_TRIBalance_Before, "0") await openVessel({ asset: erc20.address, @@ -2668,8 +2668,8 @@ contract("BorrowerOperations", async accounts => { extraParams: { from: D }, }) - const Treasury_TRIBalance_After = await debtToken.balanceOf(treasury) - assert.isTrue(Treasury_TRIBalance_After.gt(Treasury_TRIBalance_Before)) + const Distributor_TRIBalance_After = await debtToken.balanceOf(distributor) + assert.isTrue(Distributor_TRIBalance_After.gt(Distributor_TRIBalance_Before)) }) if (!withProxy) { @@ -2752,8 +2752,8 @@ contract("BorrowerOperations", async accounts => { // time fast-forwards 1 year await th.fastForwardTime(timeValues.SECONDS_IN_ONE_YEAR, web3.currentProvider) - const Treasury_TRIBalance_Before = await debtToken.balanceOf(treasury) - assert.equal(Treasury_TRIBalance_Before, "0") + const Distributor_TRIBalance_Before = await debtToken.balanceOf(distributor) + assert.equal(Distributor_TRIBalance_Before, "0") await openVessel({ asset: erc20.address, @@ -2804,7 +2804,7 @@ contract("BorrowerOperations", async accounts => { // D adjusts vessel const TRIRequest_D = toBN(dec(40, 18)) - const Treasury_TRIBalance_After = await debtToken.balanceOf(treasury) + const Distributor_TRIBalance_After = await debtToken.balanceOf(distributor) // Check D's TRI balance has increased by their requested TRI const D_TRIBalanceAfter = await debtToken.balanceOf(D) @@ -2813,8 +2813,8 @@ contract("BorrowerOperations", async accounts => { from: D, }) - const Treasury_TRIBalance_After_Asset = await debtToken.balanceOf(treasury) - assert.isTrue(Treasury_TRIBalance_After_Asset.gt(Treasury_TRIBalance_After)) + const Distributor_TRIBalance_After_Asset = await debtToken.balanceOf(distributor) + assert.isTrue(Distributor_TRIBalance_After_Asset.gt(Distributor_TRIBalance_After)) // Check D's TRI balance has increased by their requested TRI const D_TRIBalanceAfter_Asset = await debtToken.balanceOf(D) @@ -2822,7 +2822,7 @@ contract("BorrowerOperations", async accounts => { }) // NOTE: Logic changed - it("adjustVessel(): borrowing at zero borrowing fee doesn't TRI balance of treasury contract", async () => { + it("adjustVessel(): borrowing at zero borrowing fee doesn't TRI balance of distributor contract", async () => { await openVessel({ asset: erc20.address, ICR: toBN(dec(10, 18)), @@ -2864,17 +2864,17 @@ contract("BorrowerOperations", async accounts => { await th.fastForwardTime(7200, web3.currentProvider) // Check staking TRI balance before > 0 - const Treasury_TRIBalance_Before = await debtToken.balanceOf(treasury) - assert.isTrue(Treasury_TRIBalance_Before.gt(toBN("0"))) + const Distributor_TRIBalance_Before = await debtToken.balanceOf(distributor) + assert.isTrue(Distributor_TRIBalance_Before.gt(toBN("0"))) // D adjusts vessel - const Treasury_TRIBalance_After = await debtToken.balanceOf(treasury) + const Distributor_TRIBalance_After = await debtToken.balanceOf(distributor) await borrowerOperations.adjustVessel(erc20.address, 0, 0, dec(37, 18), true, D, D, { from: D, }) - const Treasury_TRIBalance_After_Asset = await debtToken.balanceOf(treasury) - assert.isTrue(Treasury_TRIBalance_After_Asset.eq(Treasury_TRIBalance_After)) + const Distributor_TRIBalance_After_Asset = await debtToken.balanceOf(distributor) + assert.isTrue(Distributor_TRIBalance_After_Asset.eq(Distributor_TRIBalance_After)) }) it("adjustVessel(): borrowing at zero base rate sends total requested TRI to the user", async () => { @@ -3409,8 +3409,8 @@ contract("BorrowerOperations", async accounts => { assert.isTrue(await th.checkRecoveryMode(contracts.core, erc20.address)) - const TreasuryTRIBalanceBefore = await debtToken.balanceOf(treasury) - assert.isTrue(TreasuryTRIBalanceBefore.gt(toBN("0"))) + const DistributorTRIBalanceBefore = await debtToken.balanceOf(distributor) + assert.isTrue(DistributorTRIBalanceBefore.gt(toBN("0"))) const txAlice_Asset = await borrowerOperations.adjustVessel( erc20.address, @@ -3434,8 +3434,8 @@ contract("BorrowerOperations", async accounts => { assert.isTrue(await th.checkRecoveryMode(contracts.core, erc20.address)) // Check no fee was sent to staking contract - const TreasuryTRIBalanceAfter = await debtToken.balanceOf(treasury) - assert.equal(TreasuryTRIBalanceAfter.toString(), TreasuryTRIBalanceBefore.toString()) + const DistributorTRIBalanceAfter = await debtToken.balanceOf(distributor) + assert.equal(DistributorTRIBalanceAfter.toString(), DistributorTRIBalanceBefore.toString()) }) it("adjustVessel(): reverts when change would cause the TCR of the system to fall below the CCR", async () => { @@ -5628,12 +5628,12 @@ contract("BorrowerOperations", async accounts => { assert.isTrue(baseRate_2_Asset.lt(baseRate_1_Asset)) }) */ - it("openVessel(): borrowing at non-zero base rate sends TRI fee to treasury contract", async () => { + it("openVessel(): borrowing at non-zero base rate sends TRI fee to distributor contract", async () => { // time fast-forwards 1 year await th.fastForwardTime(timeValues.SECONDS_IN_ONE_YEAR, web3.currentProvider) - const Treasury_TRIBalance_Before = await debtToken.balanceOf(treasury) - assert.equal(Treasury_TRIBalance_Before, "0") + const Distributor_TRIBalance_Before = await debtToken.balanceOf(distributor) + assert.equal(Distributor_TRIBalance_Before, "0") await openVessel({ asset: erc20.address, @@ -5682,8 +5682,8 @@ contract("BorrowerOperations", async accounts => { extraParams: { from: D }, }) - const Treasury_TRIBalance_After = await debtToken.balanceOf(treasury) - assert.isTrue(Treasury_TRIBalance_After.gt(Treasury_TRIBalance_Before)) + const Distributor_TRIBalance_After = await debtToken.balanceOf(distributor) + assert.isTrue(Distributor_TRIBalance_After.gt(Distributor_TRIBalance_Before)) }) if (!withProxy) { @@ -5760,8 +5760,8 @@ contract("BorrowerOperations", async accounts => { it("openVessel(): borrowing at non-zero base rate sends requested amount to the user", async () => { await th.fastForwardTime(timeValues.SECONDS_IN_ONE_YEAR, web3.currentProvider) - const Treasury_TRIBalance_Before = await debtToken.balanceOf(treasury) - assert.equal(Treasury_TRIBalance_Before, "0") + const Distributor_TRIBalance_Before = await debtToken.balanceOf(distributor) + assert.equal(Distributor_TRIBalance_Before, "0") await openVessel({ asset: erc20.address, @@ -5806,8 +5806,8 @@ contract("BorrowerOperations", async accounts => { const TRIRequest_D = toBN(dec(40000, 18)) await borrowerOperations.openVessel(erc20.address, dec(500, "ether"), TRIRequest_D, D, D, { from: D }) - const Treasury_TRIBalance_After = await debtToken.balanceOf(treasury) - assert.isTrue(Treasury_TRIBalance_After.gt(Treasury_TRIBalance_Before)) + const Distributor_TRIBalance_After = await debtToken.balanceOf(distributor) + assert.isTrue(Distributor_TRIBalance_After.gt(Distributor_TRIBalance_Before)) // Check D's TRI balance now equals their requested TRI const TRIBalance_D = await debtToken.balanceOf(D) diff --git a/test/trinity/BorrowerOperations_FeesTest.js b/test/trinity/BorrowerOperations_FeesTest.js index 032aa78..5913315 100644 --- a/test/trinity/BorrowerOperations_FeesTest.js +++ b/test/trinity/BorrowerOperations_FeesTest.js @@ -10,7 +10,7 @@ const {_1e18BN} = testHelpers.MoneyValues contract("BorrowerOperations_Fees", async accounts => { - const [owner, alice, bob, treasury] = accounts + const [_, alice, bob, treasury, distributor] = accounts let contracts let snapshotId @@ -66,7 +66,7 @@ contract("BorrowerOperations_Fees", async accounts => { } before(async () => { - contracts = await deploymentHelper.deployTestContracts(treasury, []) + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, []) for (const acc of accounts.slice(0, 20)) { await contracts.core.erc20.mint(acc, await web3.eth.getBalance(acc)) @@ -91,16 +91,16 @@ contract("BorrowerOperations_Fees", async accounts => { it('pays initial fee', async () => { const {debtToken, erc20} = contracts.core - const initialTreasuryBalance = await debtToken.balanceOf(treasury) - assert.isTrue(initialTreasuryBalance.eq(toBN(0))) + const initialDistributorBalance = await debtToken.balanceOf(distributor) + assert.isTrue(initialDistributorBalance.eq(toBN(0))) await openVessel(alice) const vesselTRIAmount_Asset = await th.getOpenVesselTRIAmount(contracts.core, vesselTotalDebt, erc20.address) const expectedFeeAmount = vesselTRIAmount_Asset.mul(borrowingFee).div(_1e18BN).toString() - const treasuryBalance = await debtToken.balanceOf(treasury) + const distributorBalance = await debtToken.balanceOf(distributor) - assert.equal(treasuryBalance, expectedFeeAmount) + assert.equal(distributorBalance, expectedFeeAmount) }) it('updates epoch', async () => { @@ -218,23 +218,23 @@ contract("BorrowerOperations_Fees", async accounts => { await skipToNextEpoch() const debtBeforeFeeCollection = await contracts.core.vesselManager.getVesselDebt(erc20.address, alice) - const treasuryBalanceBeforeFeeCollection = await debtToken.balanceOf(treasury) + const distributorBalanceBeforeFeeCollection = await debtToken.balanceOf(distributor) await borrowerOperations.collectVesselFee(erc20.address, alice) - const treasuryBalancePostFeeCollection = await debtToken.balanceOf(treasury) + const distributorBalancePostFeeCollection = await debtToken.balanceOf(distributor) const expectedFee = getFee(debtBeforeFeeCollection) - assert.equal(treasuryBalancePostFeeCollection.toString(), treasuryBalanceBeforeFeeCollection.add(expectedFee).toString()) + assert.equal(distributorBalancePostFeeCollection.toString(), distributorBalanceBeforeFeeCollection.add(expectedFee).toString()) // bob opens vessel so alice can close hers await openVessel(bob) - const treasuryBalanceBeforeClose = await debtToken.balanceOf(treasury) + const distributorBalanceBeforeClose = await debtToken.balanceOf(distributor) await th.fastForwardTime(SECONDS_IN_ONE_WEEK / 2, web3.currentProvider) await mintDebtTokens(alice, vesselTotalDebt) await closeVessel(alice) - const treasuryBalancePostClose = await debtToken.balanceOf(treasury) - assert.equal(treasuryBalancePostClose.toString(), treasuryBalanceBeforeClose.toString()) + const distributorBalancePostClose = await debtToken.balanceOf(distributor) + assert.equal(distributorBalancePostClose.toString(), distributorBalanceBeforeClose.toString()) }) it('skips due fee payment when called before collectVesselFee', async () => { @@ -243,23 +243,23 @@ contract("BorrowerOperations_Fees", async accounts => { await skipToNextEpoch() const debtBeforeFeeCollection = await contracts.core.vesselManager.getVesselDebt(erc20.address, alice) - const treasuryBalanceBeforeFeeCollection = await debtToken.balanceOf(treasury) + const distributorBalanceBeforeFeeCollection = await debtToken.balanceOf(distributor) await borrowerOperations.collectVesselFee(erc20.address, alice) - const treasuryBalancePostFeeCollection = await debtToken.balanceOf(treasury) + const distributorBalancePostFeeCollection = await debtToken.balanceOf(distributor) const expectedFee = getFee(debtBeforeFeeCollection) - assert.equal(treasuryBalancePostFeeCollection.toString(), treasuryBalanceBeforeFeeCollection.add(expectedFee).toString()) + assert.equal(distributorBalancePostFeeCollection.toString(), distributorBalanceBeforeFeeCollection.add(expectedFee).toString()) // bob opens vessel so alice can close hers await openVessel(bob) - const treasuryBalanceBeforeClose = await debtToken.balanceOf(treasury) + const distributorBalanceBeforeClose = await debtToken.balanceOf(distributor) await skipToNextEpoch() await mintDebtTokens(alice, vesselTotalDebt) await closeVessel(alice) - const treasuryBalancePostClose = await debtToken.balanceOf(treasury) - assert.equal(treasuryBalancePostClose.toString(), treasuryBalanceBeforeClose.toString()) + const distributorBalancePostClose = await debtToken.balanceOf(distributor) + assert.equal(distributorBalancePostClose.toString(), distributorBalanceBeforeClose.toString()) }) }) diff --git a/test/trinity/CollSurplusPoolTest.js b/test/trinity/CollSurplusPoolTest.js index de99249..a44c80a 100644 --- a/test/trinity/CollSurplusPoolTest.js +++ b/test/trinity/CollSurplusPoolTest.js @@ -12,8 +12,8 @@ var snapshotId var initialSnapshotId const openVessel = async params => th.openVessel(contracts.core, params) -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -34,10 +34,10 @@ const deploy = async (treasury, mintingAccounts) => { } contract("CollSurplusPool", async accounts => { - const [A, B, treasury] = accounts + const [A, B, treasury, distributor] = accounts before(async () => { - await deploy(treasury, accounts.slice(0, 2)) + await deploy(treasury, distributor, accounts.slice(0, 2)) initialSnapshotId = await network.provider.send("evm_snapshot") }) diff --git a/test/trinity/ConnectContractsTest.js b/test/trinity/ConnectContractsTest.js index 1a4e855..8f46ad0 100644 --- a/test/trinity/ConnectContractsTest.js +++ b/test/trinity/ConnectContractsTest.js @@ -5,8 +5,8 @@ var contracts var snapshotId var initialSnapshotId -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -27,7 +27,7 @@ const deploy = async (treasury, mintingAccounts) => { contract("Deployment script - Sets correct contract addresses dependencies after deployment", async accounts => { before(async () => { - await deploy(accounts[0], []) + await deploy(accounts[0],accounts[1], []) }) // Skipping as the setAddresses() functions were replaced by constants diff --git a/test/trinity/DebtTokenTest.js b/test/trinity/DebtTokenTest.js index e530f9d..0cb9092 100644 --- a/test/trinity/DebtTokenTest.js +++ b/test/trinity/DebtTokenTest.js @@ -9,11 +9,11 @@ var snapshotId var initialSnapshotId contract("DebtToken", async accounts => { - const [owner, alice, bob, carol, dennis, treasury] = accounts + const [owner, alice, bob, carol, dennis, treasury, distributor] = accounts let debtToken, stabilityPool before(async () => { - const contracts = await deploymentHelper.deployTestContracts(treasury, []) + const contracts = await deploymentHelper.deployTestContracts(treasury, distributor, []) debtToken = contracts.core.debtToken stabilityPool = contracts.core.stabilityPool diff --git a/test/trinity/ERC20PermitTest.js b/test/trinity/ERC20PermitTest.js index 9045575..e1da33f 100644 --- a/test/trinity/ERC20PermitTest.js +++ b/test/trinity/ERC20PermitTest.js @@ -16,11 +16,11 @@ var snapshotId var initialSnapshotId contract("ERC20Permit", async accounts => { - const [owner, alice, bob, carol, treasury] = accounts + const [owner, alice, bob, carol, treasury, distributor] = accounts let debtToken, grvtToken before(async () => { - contracts = await deploymentHelper.deployTestContracts(treasury, []) + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, []) debtToken = contracts.core.debtToken await debtToken.unprotectedMint(alice, dec(150, 18)) diff --git a/test/trinity/GasCompensationTest.js b/test/trinity/GasCompensationTest.js index bc62ea4..d030527 100644 --- a/test/trinity/GasCompensationTest.js +++ b/test/trinity/GasCompensationTest.js @@ -11,8 +11,8 @@ var initialSnapshotId var validCollateral const openVessel = async params => th.openVessel(contracts.core, params) -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -35,7 +35,7 @@ const deploy = async (treasury, mintingAccounts) => { } contract("Gas compensation tests", async accounts => { - const [liquidator, alice, bob, carol, dennis, erin, flyn, harriet, whale, treasury] = accounts + const [liquidator, alice, bob, carol, dennis, erin, flyn, harriet, whale, treasury, distributor] = accounts const logICRs = ICRList => { for (let i = 0; i < ICRList.length; i++) { @@ -44,7 +44,7 @@ contract("Gas compensation tests", async accounts => { } before(async () => { - await deploy(treasury, accounts.slice(0, 25)) + await deploy(treasury, distributor, accounts.slice(0, 25)) initialSnapshotId = await network.provider.send("evm_snapshot") }) diff --git a/test/trinity/HintHelpers_getApproxHintTest.js b/test/trinity/HintHelpers_getApproxHintTest.js index 7c471d1..18c53b2 100644 --- a/test/trinity/HintHelpers_getApproxHintTest.js +++ b/test/trinity/HintHelpers_getApproxHintTest.js @@ -12,8 +12,8 @@ var contracts var snapshotId var initialSnapshotId -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -90,7 +90,7 @@ contract("VesselManagerOperations-HintHelpers", async accounts => { before(async () => { - await deploy(accounts[0], accounts.slice(0, 10)) + await deploy(accounts[0], accounts[11], accounts.slice(0, 10)) numAccounts = 10 await priceFeed.setPrice(erc20.address, dec(100, 18)) diff --git a/test/trinity/PoolsTest.js b/test/trinity/PoolsTest.js index 6c0178d..c183e56 100644 --- a/test/trinity/PoolsTest.js +++ b/test/trinity/PoolsTest.js @@ -6,8 +6,8 @@ var contracts var snapshotId var initialSnapshotId -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -28,11 +28,11 @@ const deploy = async (treasury, mintingAccounts) => { } contract("Pools Test", async accounts => { - const [token1, token2, token3, treasury] = accounts + const [token1, token2, token3, treasury, distributor] = accounts const tokens = [token1, token2, token3] before(async () => { - await deploy(treasury, accounts.slice(0, 5)) + await deploy(treasury, distributor, accounts.slice(0, 5)) await setBalance(borrowerOperations.address, 1e18) await setBalance(vesselManager.address, 1e18) diff --git a/test/trinity/PriceFeedTest.js b/test/trinity/PriceFeedTest.js index 937cd41..3dea367 100644 --- a/test/trinity/PriceFeedTest.js +++ b/test/trinity/PriceFeedTest.js @@ -87,8 +87,8 @@ contract("PriceFeed", async accounts => { setBalance(timelock.address, 1e18) // only addresses considered in the tests are timelock and vesselManagerOperations - const addresses = new Array(14).fill(timelock.address, 0) - addresses[13] = vesselManagerOperations.address + const addresses = new Array(15).fill(timelock.address, 0) + addresses[14] = vesselManagerOperations.address await priceFeed.setAddresses(addresses) await setOracle(ZERO_ADDRESS, mockOracle.address) }) diff --git a/test/trinity/SortedVesselsTest.js b/test/trinity/SortedVesselsTest.js index 158c25d..ba50cb8 100644 --- a/test/trinity/SortedVesselsTest.js +++ b/test/trinity/SortedVesselsTest.js @@ -12,8 +12,8 @@ var snapshotId var initialSnapshotId const openVessel = async params => th.openVessel(contracts.core, params) -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -56,12 +56,12 @@ contract("SortedVessels", async accounts => { } } - const [alice, bob, carol, dennis, erin, defaulter_1, A, B, C, D, E, F, G, H, I, J, whale, treasury] = accounts + const [alice, bob, carol, dennis, erin, defaulter_1, A, B, C, D, E, F, G, H, I, J, whale, treasury, distributor] = accounts describe("SortedVessels", () => { before(async () => { - await deploy(treasury, accounts.slice(0, 20)) + await deploy(treasury, distributor, accounts.slice(0, 20)) initialSnapshotId = await network.provider.send("evm_snapshot") }) @@ -411,7 +411,7 @@ contract("SortedVessels", async accounts => { sortedVesselsTester = await SortedVesselsTester.new() await sortedVessels.initialize() - const addresses = new Array(14).fill(sortedVesselsTester.address, 0) + const addresses = new Array(15).fill(sortedVesselsTester.address, 0) await sortedVessels.setAddresses(addresses) await sortedVesselsTester.setSortedVessels(sortedVessels.address) diff --git a/test/trinity/StabilityPoolTest.js b/test/trinity/StabilityPoolTest.js index 5faa1b3..c60596c 100644 --- a/test/trinity/StabilityPoolTest.js +++ b/test/trinity/StabilityPoolTest.js @@ -11,8 +11,8 @@ var snapshotId var initialSnapshotId const openVessel = async params => th.openVessel(contracts.core, params) -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -56,6 +56,7 @@ contract("StabilityPool", async accounts => { flyn, graham, treasury, + distributor, ] = accounts const getOpenVesselTRIAmount = async (totalDebt, asset) => @@ -102,7 +103,7 @@ contract("StabilityPool", async accounts => { describe("Stability Pool Mechanisms", async () => { before(async () => { - await deploy(treasury, accounts.slice(0, 20)) + await deploy(treasury, distributor, accounts.slice(0, 20)) initialSnapshotId = await network.provider.send("evm_snapshot") }) diff --git a/test/trinity/VesselManagerTest.js b/test/trinity/VesselManagerTest.js index b16d653..14f5b73 100644 --- a/test/trinity/VesselManagerTest.js +++ b/test/trinity/VesselManagerTest.js @@ -20,8 +20,8 @@ var snapshotId var initialSnapshotId var validCollateral -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -84,6 +84,7 @@ contract("VesselManager", async accounts => { D, E, treasury, + distributor, ] = accounts const multisig = accounts[999] @@ -100,7 +101,7 @@ contract("VesselManager", async accounts => { describe("Vessel Manager", async () => { before(async () => { - await deploy(treasury, accounts.slice(0, 20)) + await deploy(treasury, distributor, accounts.slice(0, 20)) // give some gas to the contracts that will be impersonated setBalance(adminContract.address, 1e18) diff --git a/test/trinity/VesselManager_LiquidationRewardsTest.js b/test/trinity/VesselManager_LiquidationRewardsTest.js index a6004b7..7c65d3f 100644 --- a/test/trinity/VesselManager_LiquidationRewardsTest.js +++ b/test/trinity/VesselManager_LiquidationRewardsTest.js @@ -8,8 +8,8 @@ var contracts var snapshotId var initialSnapshotId -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -31,13 +31,13 @@ const deploy = async (treasury, mintingAccounts) => { } contract("VesselManager - Redistribution reward calculations", async accounts => { - const [owner, alice, bob, carol, dennis, erin, freddy, A, B, C, D, E, treasury] = accounts + const [owner, alice, bob, carol, dennis, erin, freddy, A, B, C, D, E, treasury, distributor] = accounts const getNetBorrowingAmount = async (debtWithFee, asset) => th.getNetBorrowingAmount(contracts.core, debtWithFee, asset) const openVessel = async params => th.openVessel(contracts.core, params) before(async () => { - await deploy(treasury, accounts.slice(0, 20)) + await deploy(treasury, distributor, accounts.slice(0, 20)) initialSnapshotId = await network.provider.send("evm_snapshot") }) diff --git a/test/trinity/VesselManager_RecoveryModeTest.js b/test/trinity/VesselManager_RecoveryModeTest.js index 7f38204..0a0b460 100644 --- a/test/trinity/VesselManager_RecoveryModeTest.js +++ b/test/trinity/VesselManager_RecoveryModeTest.js @@ -17,8 +17,8 @@ var snapshotId var initialSnapshotId var validCollateral -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -88,6 +88,7 @@ contract("VesselManager - in Recovery Mode", async accounts => { H, I, treasury, + distributor, ] = accounts let REDEMPTION_SOFTENING_PARAM @@ -104,7 +105,7 @@ contract("VesselManager - in Recovery Mode", async accounts => { } before(async () => { - await deploy(treasury, accounts.slice(0, 40)) + await deploy(treasury, distributor, accounts.slice(0, 40)) await setBalance(shortTimelock.address, 1e18) await impersonateAccount(shortTimelock.address) await vesselManagerOperations.setRedemptionSofteningParam("9700", { from: shortTimelock.address }) diff --git a/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js b/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js index c185123..eb9c630 100644 --- a/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js +++ b/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js @@ -14,8 +14,8 @@ var snapshotId var initialSnapshotId var validCollateral -const deploy = async (treasury, mintingAccounts) => { - contracts = await deploymentHelper.deployTestContracts(treasury, mintingAccounts) +const deploy = async (treasury, distributor, mintingAccounts) => { + contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) activePool = contracts.core.activePool adminContract = contracts.core.adminContract @@ -42,12 +42,12 @@ const deploy = async (treasury, mintingAccounts) => { } contract("VesselManager - in Recovery Mode - back to normal mode in 1 tx", async accounts => { - const [alice, bob, carol, whale, treasury] = accounts + const [alice, bob, carol, whale, treasury, distributor] = accounts const openVessel = async params => th.openVessel(contracts.core, params) before(async () => { - await deploy(treasury, accounts.slice(0, 20)) + await deploy(treasury, distributor, accounts.slice(0, 20)) initialSnapshotId = await network.provider.send("evm_snapshot") }) diff --git a/test/utils/deploymentHelpers.js b/test/utils/deploymentHelpers.js index a082f97..f493db2 100644 --- a/test/utils/deploymentHelpers.js +++ b/test/utils/deploymentHelpers.js @@ -26,9 +26,9 @@ const TIMELOCK_LONG_DELAY = 86400 * 7 * Deploys Trinity's contracts to Hardhat TEST env */ class DeploymentHelper { - static async deployTestContracts(treasuryAddress, collateralMintingAccounts = []) { + static async deployTestContracts(treasuryAddress, distributorAddress, collateralMintingAccounts = []) { const core = await this._deployCoreContracts(treasuryAddress) - await this._connectCoreContracts(core, treasuryAddress) + await this._connectCoreContracts(core, treasuryAddress, distributorAddress) await this._connectGrvtContracts(core) for (const acc of collateralMintingAccounts) { @@ -101,7 +101,7 @@ class DeploymentHelper { /** * Connects contracts to their dependencies. */ - static async _connectCoreContracts(core, treasuryAddress) { + static async _connectCoreContracts(core, treasuryAddress, distributorAddress) { const setAddresses = async contract => { const addresses = [ core.activePool.address, @@ -110,6 +110,7 @@ class DeploymentHelper { core.collSurplusPool.address, core.debtToken.address, core.defaultPool.address, + distributorAddress, core.gasPool.address, core.priceFeedTestnet.address, core.sortedVessels.address, From 6c0c7eeece9547ed8644d6c1463f7ef6d75ced0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Stankiewicz?= Date: Mon, 6 May 2024 09:27:02 +0200 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=90=9D=20Add=20liquidators=20whitelis?= =?UTF-8?q?t=20(#12)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🐝 Add liquidators whitelist * Make tests more robust --------- Co-authored-by: szymx95 --- contracts/AdminContract.sol | 11 ++++ contracts/Interfaces/IAdminContract.sol | 5 ++ .../Interfaces/IVesselManagerOperations.sol | 1 + contracts/VesselManagerOperations.sol | 9 +++ test/trinity/AdminContractTest.js | 12 ++++ test/trinity/BorrowerOperationsTest.js | 6 +- test/trinity/CollSurplusPoolTest.js | 4 ++ test/trinity/GasCompensationTest.js | 4 ++ test/trinity/StabilityPoolTest.js | 17 +++-- test/trinity/VesselManagerTest.js | 64 ++++++++++++++++--- .../VesselManager_LiquidationRewardsTest.js | 4 ++ .../trinity/VesselManager_RecoveryModeTest.js | 1 + ...nager_RecoveryMode_BatchLiquidationTest.js | 4 ++ 13 files changed, 128 insertions(+), 14 deletions(-) diff --git a/contracts/AdminContract.sol b/contracts/AdminContract.sol index e80d7ca..a7ce2be 100644 --- a/contracts/AdminContract.sol +++ b/contracts/AdminContract.sol @@ -40,6 +40,8 @@ contract AdminContract is IAdminContract, UUPSUpgradeable, OwnableUpgradeable, A mapping(address => mapping(address => bool)) internal collateralWhitelistedAddresses; + mapping(address => bool) internal whitelistedLiquidators; + // list of all collateral types in collateralParams (active and deprecated) // Addresses for easy access address[] public validCollateral; // index maps to token address. @@ -257,6 +259,11 @@ contract AdminContract is IAdminContract, UUPSUpgradeable, OwnableUpgradeable, A emit AddressCollateralWhitelisted(_collateral, _address, _whitelisted); } + function setLiquidatorWhitelisted(address _liquidator, bool _whitelisted) external onlyTimelock { + whitelistedLiquidators[_liquidator] = _whitelisted; + emit LiquidatorWhitelisted(_liquidator, _whitelisted); + } + function setRedemptionBaseFeeEnabled(address _collateral, bool _enabled) external onlyTimelock { collateralParams[_collateral].redemptionBaseFeeEnabled = _enabled; emit BaseFeeEnabledChanged(_collateral, _enabled); @@ -333,6 +340,10 @@ contract AdminContract is IAdminContract, UUPSUpgradeable, OwnableUpgradeable, A return collateralWhitelistedAddresses[_collateral][_address]; } + function getIsLiquidatorWhitelisted(address _liquidator) external view returns (bool) { + return whitelistedLiquidators[_liquidator]; + } + function getRedemptionBaseFeeEnabled(address _collateral) external view override returns (bool) { return collateralParams[_collateral].redemptionBaseFeeEnabled; } diff --git a/contracts/Interfaces/IAdminContract.sol b/contracts/Interfaces/IAdminContract.sol index fa49211..b4f320e 100644 --- a/contracts/Interfaces/IAdminContract.sol +++ b/contracts/Interfaces/IAdminContract.sol @@ -45,6 +45,7 @@ interface IAdminContract { event RedemptionBlockTimestampChanged(address _collateral, uint256 _blockTimestamp); event AddressCollateralWhitelisted(address _collateral, address _address, bool _whitelisted); event BaseFeeEnabledChanged(address _collateral, bool _enabled); + event LiquidatorWhitelisted(address _liquidator, bool _whitelisted); // Functions -------------------------------------------------------------------------------------------------------- @@ -83,6 +84,8 @@ interface IAdminContract { function setAddressCollateralWhitelisted(address _collateral, address _address, bool _whitelisted) external; + function setLiquidatorWhitelisted(address _liquidator, bool _whitelisted) external; + function setRedemptionBaseFeeEnabled(address _collateral, bool _enabled) external; function getIndex(address _collateral) external view returns (uint256); @@ -111,5 +114,7 @@ interface IAdminContract { function getIsAddressCollateralWhitelisted(address _collateral, address _address) external view returns (bool); + function getIsLiquidatorWhitelisted(address _liquidator) external view returns (bool); + function getRedemptionBaseFeeEnabled(address _collateral) external view returns (bool); } diff --git a/contracts/Interfaces/IVesselManagerOperations.sol b/contracts/Interfaces/IVesselManagerOperations.sol index 8d324a3..5473559 100644 --- a/contracts/Interfaces/IVesselManagerOperations.sol +++ b/contracts/Interfaces/IVesselManagerOperations.sol @@ -49,6 +49,7 @@ interface IVesselManagerOperations is ITrinityBase { error VesselManagerOperations__InvalidParam(); error VesselManagerOperations__NotTimelock(); error VesselManagerOperations__AddressNotCollateralWhitelisted(); + error VesselManagerOperations__LiquidatorNotWhitelisted(); // Structs ---------------------------------------------------------------------------------------------------------- diff --git a/contracts/VesselManagerOperations.sol b/contracts/VesselManagerOperations.sol index 0e54e6f..96cab5b 100644 --- a/contracts/VesselManagerOperations.sol +++ b/contracts/VesselManagerOperations.sol @@ -59,6 +59,11 @@ contract VesselManagerOperations is IVesselManagerOperations, UUPSUpgradeable, R * starting from the one with the lowest collateral ratio in the system, and moving upwards. */ function liquidateVessels(address _asset, uint256 _n) external override nonReentrant { + address liquidator = msg.sender; + if (!IAdminContract(adminContract).getIsLiquidatorWhitelisted(liquidator)) { + revert VesselManagerOperations__LiquidatorNotWhitelisted(); + } + LocalVariables_OuterLiquidationFunction memory vars; LiquidationTotals memory totals; vars.price = IPriceFeed(priceFeed).fetchPrice(_asset); @@ -102,6 +107,10 @@ contract VesselManagerOperations is IVesselManagerOperations, UUPSUpgradeable, R * Attempt to liquidate a custom list of vessels provided by the caller. */ function batchLiquidateVessels(address _asset, address[] memory _vesselArray) public override nonReentrant { + address liquidator = msg.sender; + if (!IAdminContract(adminContract).getIsLiquidatorWhitelisted(liquidator)) { + revert VesselManagerOperations__LiquidatorNotWhitelisted(); + } if (_vesselArray.length == 0 || _vesselArray.length > BATCH_SIZE_LIMIT) { revert VesselManagerOperations__InvalidArraySize(); } diff --git a/test/trinity/AdminContractTest.js b/test/trinity/AdminContractTest.js index 0b562f1..5654b04 100644 --- a/test/trinity/AdminContractTest.js +++ b/test/trinity/AdminContractTest.js @@ -320,6 +320,18 @@ contract("AdminContract", async accounts => { await assertRevert(adminContract.setAddressCollateralWhitelisted(erc20.address, ZERO_ADDRESS, false, {from: user})) }) + it('setLiquidatorWhitelisted: Owner change parameter - Valid Owner', async () => { + await adminContract.setLiquidatorWhitelisted(ZERO_ADDRESS, true) + assert.isTrue(await adminContract.getIsLiquidatorWhitelisted(ZERO_ADDRESS)) + await adminContract.setLiquidatorWhitelisted(ZERO_ADDRESS, false) + assert.isFalse(await adminContract.getIsLiquidatorWhitelisted(ZERO_ADDRESS)) + }) + + it('setLiquidatorWhitelisted: Owner change parameter - Invalid Owner', async () => { + await assertRevert(adminContract.setLiquidatorWhitelisted(ZERO_ADDRESS, true, {from: user})) + await assertRevert(adminContract.setLiquidatorWhitelisted(ZERO_ADDRESS, false, {from: user})) + }) + it('setRedemptionBaseFeeEnabled: Owner change parameter - Valid Owner', async () => { await adminContract.setRedemptionBaseFeeEnabled(ZERO_ADDRESS, true) assert.isTrue(await adminContract.getRedemptionBaseFeeEnabled(ZERO_ADDRESS)) diff --git a/test/trinity/BorrowerOperationsTest.js b/test/trinity/BorrowerOperationsTest.js index dbf73eb..7236563 100644 --- a/test/trinity/BorrowerOperationsTest.js +++ b/test/trinity/BorrowerOperationsTest.js @@ -40,6 +40,10 @@ const deploy = async (treasury, distributor, mintingAccounts) => { vesselManagerOperations = contracts.core.vesselManagerOperations shortTimelock = contracts.core.shortTimelock longTimelock = contracts.core.longTimelock + + for(const account of mintingAccounts) { + await adminContract.setLiquidatorWhitelisted(account, true) + } } contract("BorrowerOperations", async accounts => { @@ -59,7 +63,7 @@ contract("BorrowerOperations", async accounts => { describe("BorrowerOperations Mechanisms", async () => { before(async () => { - await deploy(treasury, distributor, []) + await deploy(treasury, distributor, accounts.slice(0, 20)) MIN_NET_DEBT_ERC20 = await adminContract.getMinNetDebt(erc20.address) BORROWING_FEE_ERC20 = await adminContract.getBorrowingFee(erc20.address) diff --git a/test/trinity/CollSurplusPoolTest.js b/test/trinity/CollSurplusPoolTest.js index a44c80a..9a15c66 100644 --- a/test/trinity/CollSurplusPoolTest.js +++ b/test/trinity/CollSurplusPoolTest.js @@ -31,6 +31,10 @@ const deploy = async (treasury, distributor, mintingAccounts) => { vesselManagerOperations = contracts.core.vesselManagerOperations shortTimelock = contracts.core.shortTimelock longTimelock = contracts.core.longTimelock + + for(const account of mintingAccounts) { + await adminContract.setLiquidatorWhitelisted(account, true) + } } contract("CollSurplusPool", async accounts => { diff --git a/test/trinity/GasCompensationTest.js b/test/trinity/GasCompensationTest.js index d030527..fea240a 100644 --- a/test/trinity/GasCompensationTest.js +++ b/test/trinity/GasCompensationTest.js @@ -32,6 +32,10 @@ const deploy = async (treasury, distributor, mintingAccounts) => { longTimelock = contracts.core.longTimelock validCollateral = await adminContract.getValidCollateral() + + for(const account of mintingAccounts) { + await adminContract.setLiquidatorWhitelisted(account, true) + } } contract("Gas compensation tests", async accounts => { diff --git a/test/trinity/StabilityPoolTest.js b/test/trinity/StabilityPoolTest.js index c60596c..ac9f26d 100644 --- a/test/trinity/StabilityPoolTest.js +++ b/test/trinity/StabilityPoolTest.js @@ -6,9 +6,10 @@ const mv = testHelpers.MoneyValues const timeValues = testHelpers.TimeValues var contracts -var validCollateral var snapshotId var initialSnapshotId +var validCollateral +var unsortedCollaterals const openVessel = async params => th.openVessel(contracts.core, params) const deploy = async (treasury, distributor, mintingAccounts) => { @@ -33,9 +34,13 @@ const deploy = async (treasury, distributor, mintingAccounts) => { longTimelock = contracts.core.longTimelock validCollateral = await adminContract.getValidCollateral() - + unsortedCollaterals = validCollateral.slice(0) // 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.setLiquidatorWhitelisted(account, true) + } } contract("StabilityPool", async accounts => { @@ -1128,8 +1133,9 @@ contract("StabilityPool", async accounts => { // Expect alice to be entitled to 1000/200000 of the liquidated coll const aliceExpectedGainERC20 = liquidatedCollERC20.mul(toBN(dec(1000, 18))).div(toBN(dec(200_000, 18))) - const idx = validCollateral.indexOf(erc20.address) - const aliceGainERC20 = (await stabilityPool.getDepositorGains(alice, validCollateral))[1][idx] + + const aliceDepositorGains = await stabilityPool.getDepositorGains(alice, validCollateral) + const aliceGainERC20 = aliceDepositorGains[1][aliceDepositorGains[0].indexOf(erc20.address)] assert.isTrue(aliceExpectedGainERC20.eq(aliceGainERC20)) // Alice withdraws from SP, chooses not to receive gains to avoid transfer/swap costs @@ -1146,7 +1152,8 @@ contract("StabilityPool", async accounts => { await stabilityPool.withdrawFromSP(dec(199_000, 18), validCollateral, { from: whale }) const stability_col_AfterWhaleERC20 = await stabilityPool.getCollateral(erc20.address) - const lastAssetError_Offset= (await stabilityPool.lastAssetError_Offset(idx)).div(toBN(10).pow(toBN(18))) + 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))) }) diff --git a/test/trinity/VesselManagerTest.js b/test/trinity/VesselManagerTest.js index 14f5b73..0d34086 100644 --- a/test/trinity/VesselManagerTest.js +++ b/test/trinity/VesselManagerTest.js @@ -19,6 +19,7 @@ var contracts var snapshotId var initialSnapshotId var validCollateral +var unsortedCollaterals const deploy = async (treasury, distributor, mintingAccounts) => { contracts = await deploymentHelper.deployTestContracts(treasury, distributor, mintingAccounts) @@ -42,12 +43,13 @@ const deploy = async (treasury, distributor, mintingAccounts) => { longTimelock = contracts.core.longTimelock validCollateral = await adminContract.getValidCollateral() - + unsortedCollaterals = validCollateral.slice(0) // 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) + await adminContract.setLiquidatorWhitelisted(account, true) } } @@ -131,6 +133,24 @@ contract("VesselManager", async accounts => { }) describe("Liquidations", async () => { + it("liquidate(): reverts when not whitelisted", async () => { + await openVessel({ + asset: erc20.address, + ICR: toBN(dec(4, 18)), + extraParams: { from: alice }, + }) + + await adminContract.setLiquidatorWhitelisted(alice, false) + + try { + const tx = await vesselManagerOperations.liquidate(erc20.address, alice, {from: alice}) + assert.isFalse(tx.receipt.status) + } catch (err) { + assert.include(err.message, "revert") + assert.include(err.message, "VesselManagerOperations__LiquidatorNotWhitelisted()") + } + }) + it("liquidate(): closes a Vessel that has ICR < MCR", async () => { await openVessel({ asset: erc20.address, @@ -1150,8 +1170,10 @@ contract("VesselManager", async accounts => { // Check Bob' SP deposit has absorbed Carol's debt, and he has received her liquidated ETH const bob_Deposit_Before_Asset = await stabilityPool.getCompoundedDebtTokenDeposits(bob) - const idx = validCollateral.indexOf(erc20.address) - const bob_ETHGain_Before_Asset = (await stabilityPool.getDepositorGains(bob, validCollateral))[1][idx] + + + const bob_depositor_gains = (await stabilityPool.getDepositorGains(bob, validCollateral)) + const bob_ETHGain_Before_Asset = bob_depositor_gains[1][bob_depositor_gains[0].indexOf(erc20.address)] assert.isAtMost(th.getDifference(bob_Deposit_Before_Asset, B_spDeposit.sub(C_debt_Asset)), 1000000) assert.isAtMost(th.getDifference(bob_ETHGain_Before_Asset, C_collateral_Asset), 1000) @@ -1180,13 +1202,13 @@ contract("VesselManager", async accounts => { Check Bob' SP deposit has been reduced to 50 TRI, and his ETH gain has increased to 1.5 ETH. */ const alice_Deposit_After_Asset = (await stabilityPool.getCompoundedDebtTokenDeposits(alice)).toString() - const alice_ETHGain_After_Asset = (await stabilityPool.getDepositorGains(alice, validCollateral))[1][ - idx - ].toString() + const alice_depositor_gains = (await stabilityPool.getDepositorGains(alice, validCollateral)) + const alice_ETHGain_After_Asset = alice_depositor_gains[1][alice_depositor_gains[0].indexOf(erc20.address)].toString() const totalDeposits_Asset = bob_Deposit_Before_Asset.add(A_spDeposit) - const lastAssetError_Offset= (await stabilityPool.lastAssetError_Offset(idx)).div(toBN(10).pow(toBN(18))) + const collateral_Id = unsortedCollaterals.indexOf(erc20.address) + const lastAssetError_Offset= (await stabilityPool.lastAssetError_Offset(collateral_Id)).div(toBN(10).pow(toBN(18))) const lastDebtTokenLossError_Offset = (await stabilityPool.lastDebtTokenLossError_Offset()).div(toBN(10).pow(toBN(18))) assert.isAtMost( @@ -1205,7 +1227,10 @@ contract("VesselManager", async accounts => { ) const bob_Deposit_After_Asset = await stabilityPool.getCompoundedDebtTokenDeposits(bob) - const bob_ETHGain_After_Asset = (await stabilityPool.getDepositorGains(bob, validCollateral))[1][idx] + + const bob_depositor_gains_After_Asset = (await stabilityPool.getDepositorGains(bob, validCollateral)) + const bob_ETHGain_After_Asset = bob_depositor_gains_After_Asset[1][bob_depositor_gains_After_Asset[0].indexOf(erc20.address)] + assert.isAtMost( th.getDifference( @@ -1399,6 +1424,17 @@ contract("VesselManager", async accounts => { }) // --- liquidateVessels() --- + it("liquidateVessels(): reverts when not whitelisted", async () => { + await adminContract.setLiquidatorWhitelisted(alice, false) + + try { + const tx = await vesselManagerOperations.liquidateVessels(erc20.address, 2, {from: alice}) + assert.isFalse(tx.receipt.status) + } catch (err) { + assert.include(err.message, "revert") + assert.include(err.message, "VesselManagerOperations__LiquidatorNotWhitelisted()") + } + }) it("liquidateVessels(): liquidates a Vessel that a) was skipped in a previous liquidation and b) has pending rewards", async () => { // A, B, C, D, E open vessels @@ -2430,6 +2466,18 @@ contract("VesselManager", async accounts => { // --- batchLiquidateVessels() --- describe("Batch Liquidations", async () => { + it("batchLiquidateVessels(): reverts when not whitelisted", async () => { + await adminContract.setLiquidatorWhitelisted(alice, false) + + try { + const tx = await vesselManagerOperations.batchLiquidateVessels(erc20.address, [], {from: alice}) + assert.isFalse(tx.receipt.status) + } catch (err) { + assert.include(err.message, "revert") + assert.include(err.message, "VesselManagerOperations__LiquidatorNotWhitelisted()") + } + }) + it("batchLiquidateVessels(): liquidates a Vessel that a) was skipped in a previous liquidation and b) has pending rewards", async () => { // A, B, C, D, E open vessels diff --git a/test/trinity/VesselManager_LiquidationRewardsTest.js b/test/trinity/VesselManager_LiquidationRewardsTest.js index 7c65d3f..fb23a78 100644 --- a/test/trinity/VesselManager_LiquidationRewardsTest.js +++ b/test/trinity/VesselManager_LiquidationRewardsTest.js @@ -28,6 +28,10 @@ const deploy = async (treasury, distributor, mintingAccounts) => { vesselManagerOperations = contracts.core.vesselManagerOperations shortTimelock = contracts.core.shortTimelock longTimelock = contracts.core.longTimelock + + for(const account of mintingAccounts) { + await adminContract.setLiquidatorWhitelisted(account, true) + } } contract("VesselManager - Redistribution reward calculations", async accounts => { diff --git a/test/trinity/VesselManager_RecoveryModeTest.js b/test/trinity/VesselManager_RecoveryModeTest.js index 0a0b460..8e1b83e 100644 --- a/test/trinity/VesselManager_RecoveryModeTest.js +++ b/test/trinity/VesselManager_RecoveryModeTest.js @@ -45,6 +45,7 @@ const deploy = async (treasury, distributor, mintingAccounts) => { for(const account of mintingAccounts) { await adminContract.setAddressCollateralWhitelisted(erc20.address, account, true) + await adminContract.setLiquidatorWhitelisted(account, true) } } diff --git a/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js b/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js index eb9c630..6f03fdf 100644 --- a/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js +++ b/test/trinity/VesselManager_RecoveryMode_BatchLiquidationTest.js @@ -39,6 +39,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.setLiquidatorWhitelisted(account, true) + } } contract("VesselManager - in Recovery Mode - back to normal mode in 1 tx", async accounts => { 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 3/3] =?UTF-8?q?=F0=9F=90=B4=20Add=20stability=20pool=20whi?= =?UTF-8?q?telist=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) + } } }