Skip to content

Commit

Permalink
Merge branch 'main' into add-fee-to-both-vessel-and-global-debt
Browse files Browse the repository at this point in the history
  • Loading branch information
Szymx95 authored May 6, 2024
2 parents 538bee2 + cb1b11a commit a5f2a86
Show file tree
Hide file tree
Showing 28 changed files with 314 additions and 147 deletions.
11 changes: 11 additions & 0 deletions contracts/AdminContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/BorrowerOperations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,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;
Expand Down
22 changes: 12 additions & 10 deletions contracts/Dependencies/AddressesConfigurable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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];
Expand All @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions contracts/Dependencies/AddressesMainnet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions contracts/Interfaces/IAdminContract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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 --------------------------------------------------------------------------------------------------------

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
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
1 change: 1 addition & 0 deletions contracts/Interfaces/IVesselManagerOperations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ interface IVesselManagerOperations is ITrinityBase {
error VesselManagerOperations__InvalidParam();
error VesselManagerOperations__NotTimelock();
error VesselManagerOperations__AddressNotCollateralWhitelisted();
error VesselManagerOperations__LiquidatorNotWhitelisted();

// Structs ----------------------------------------------------------------------------------------------------------

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
9 changes: 9 additions & 0 deletions contracts/VesselManagerOperations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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();
}
Expand Down
8 changes: 4 additions & 4 deletions test/trinity/AccessControlTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down
20 changes: 16 additions & 4 deletions test/trinity/AdminContractTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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))
Expand Down
Loading

0 comments on commit a5f2a86

Please sign in to comment.