diff --git a/contracts/DebtLocker.sol b/contracts/DebtLocker.sol index 6e7f436..106fd9a 100644 --- a/contracts/DebtLocker.sol +++ b/contracts/DebtLocker.sol @@ -38,7 +38,7 @@ contract DebtLocker is IDebtLocker, DebtLockerStorage, MapleProxiedInternals { } function upgrade(uint256 toVersion_, bytes calldata arguments_) external override { - require(msg.sender == _getPoolDelegate(), "DL:U:NOT_POOL_DELEGATE"); + require(msg.sender == IMapleGlobalsLike(_getGlobals()).globalAdmin(), "DL:U:NOT_GLOBAL_ADMIN"); emit Upgraded(toVersion_, arguments_); diff --git a/contracts/interfaces/Interfaces.sol b/contracts/interfaces/Interfaces.sol index 9558d95..af780c8 100644 --- a/contracts/interfaces/Interfaces.sol +++ b/contracts/interfaces/Interfaces.sol @@ -20,6 +20,8 @@ interface IMapleGlobalsLike { function getLatestPrice(address asset_) external view returns (uint256 price_); + function globalAdmin() external view returns (address); + function investorFee() external view returns (uint256 investorFee_); function isValidCollateralAsset(address asset_) external view returns (bool isValid_); diff --git a/tests/DebtLocker.t.sol b/tests/DebtLocker.t.sol index bfd10e7..673ca24 100644 --- a/tests/DebtLocker.t.sol +++ b/tests/DebtLocker.t.sol @@ -15,6 +15,7 @@ import { DebtLockerFactory } from "../contracts/DebtLockerFactory.sol"; import { DebtLockerInitializer } from "../contracts/DebtLockerInitializer.sol"; import { DebtLockerV4Migrator } from "../contracts/DebtLockerV4Migrator.sol"; +import { GlobalAdmin } from "./accounts/GlobalAdmin.sol"; import { Governor } from "./accounts/Governor.sol"; import { PoolDelegate } from "./accounts/PoolDelegate.sol"; import { LoanMigrator } from "./accounts/LoanMigrator.sol"; @@ -42,6 +43,8 @@ interface Hevm { contract DebtLockerTests is TestUtils { DebtLockerFactory internal dlFactory; + GlobalAdmin internal globalAdmin; + GlobalAdmin internal notGlobalAdmin; Governor internal governor; MapleLoanFactory internal loanFactory; MapleLoanInitializer internal loanInitializer; @@ -58,7 +61,9 @@ contract DebtLockerTests is TestUtils { uint256 internal constant MAX_TOKEN_AMOUNT = 1e12 * 1e18; function setUp() external { + globalAdmin = new GlobalAdmin(); governor = new Governor(); + notGlobalAdmin = new GlobalAdmin(); notPoolDelegate = new PoolDelegate(); poolDelegate = new PoolDelegate(); @@ -74,6 +79,7 @@ contract DebtLockerTests is TestUtils { globals.setValidCollateralAsset(address(collateralAsset), true); globals.setValidLiquidityAsset(address(fundsAsset), true); + globals.setGlobalAdmin(address(globalAdmin)); // Deploying and registering DebtLocker implementation and initializer address debtLockerImplementation = address(new DebtLocker()); @@ -687,7 +693,7 @@ contract DebtLockerTests is TestUtils { assertEq(debtLocker.minRatio(), 100 * 10 ** 6); } - function test_acl_poolDelegate_upgrade() external { + function test_acl_globalAdmin_upgrade() external { MapleLoan loan = _createLoan(1_000_000, 30_000); DebtLocker debtLocker = DebtLocker(pool.createDebtLocker(address(dlFactory), address(loan))); @@ -705,8 +711,8 @@ contract DebtLockerTests is TestUtils { bytes memory arguments = new bytes(0); - assertTrue(!notPoolDelegate.try_debtLocker_upgrade(address(debtLocker), 2, arguments)); // Non-PD can't set - assertTrue( poolDelegate.try_debtLocker_upgrade(address(debtLocker), 2, arguments)); // PD can set + assertTrue(!notGlobalAdmin.try_debtLocker_upgrade(address(debtLocker), 2, arguments)); // Non-GA can't set + assertTrue( globalAdmin.try_debtLocker_upgrade(address(debtLocker), 2, arguments)); // GA can set assertEq(debtLocker.implementation(), dlFactory.implementationOf(2)); } @@ -1049,6 +1055,8 @@ contract DebtLockerTests is TestUtils { contract DebtLockerV4Migration is TestUtils { DebtLockerFactory internal dlFactory; + GlobalAdmin internal globalAdmin; + GlobalAdmin internal notGlobalAdmin; Governor internal governor; MapleLoanFactory internal loanFactory; MapleLoanInitializer internal loanInitializer; @@ -1063,7 +1071,9 @@ contract DebtLockerV4Migration is TestUtils { Hevm internal hevm = Hevm(address(bytes20(uint160(uint256(keccak256("hevm cheat code")))))); function setUp() external { + globalAdmin = new GlobalAdmin(); governor = new Governor(); + notGlobalAdmin = new GlobalAdmin(); notPoolDelegate = new PoolDelegate(); poolDelegate = new PoolDelegate(); @@ -1079,6 +1089,7 @@ contract DebtLockerV4Migration is TestUtils { globals.setValidCollateralAsset(address(collateralAsset), true); globals.setValidLiquidityAsset(address(fundsAsset), true); + globals.setGlobalAdmin(address(globalAdmin)); // Deploying and registering DebtLocker implementation and initializer address debtLockerImplementation = address(new DebtLocker()); @@ -1110,8 +1121,8 @@ contract DebtLockerV4Migration is TestUtils { address loanMigrator = address(5); - assertTrue(!notPoolDelegate.try_debtLocker_upgrade(address(debtLocker_), 2, abi.encode(loanMigrator))); - assertTrue( poolDelegate.try_debtLocker_upgrade(address(debtLocker_), 2, abi.encode(loanMigrator))); + assertTrue(!notGlobalAdmin.try_debtLocker_upgrade(address(debtLocker_), 2, abi.encode(loanMigrator))); + assertTrue( globalAdmin.try_debtLocker_upgrade(address(debtLocker_), 2, abi.encode(loanMigrator))); assertEq(debtLocker_.loanMigrator(), loanMigrator); } @@ -1124,7 +1135,7 @@ contract DebtLockerV4Migration is TestUtils { address newLender = address(3); - poolDelegate.debtLocker_upgrade(address(debtLocker), 2, abi.encode(address(loanMigrator))); + globalAdmin.debtLocker_upgrade(address(debtLocker), 2, abi.encode(address(loanMigrator))); assertEq(loan.pendingLender(), address(0)); @@ -1140,7 +1151,7 @@ contract DebtLockerV4Migration is TestUtils { LoanMigrator loanMigrator = new LoanMigrator(); LoanMigrator notLoanMigrator = new LoanMigrator(); - poolDelegate.debtLocker_upgrade(address(debtLocker), 2, abi.encode(address(loanMigrator))); + globalAdmin.debtLocker_upgrade(address(debtLocker), 2, abi.encode(address(loanMigrator))); loanMigrator.debtLocker_setPendingLender(address(debtLocker), address(debtLocker)); // Set pending lender in Loan to get ACL to work diff --git a/tests/accounts/GlobalAdmin.sol b/tests/accounts/GlobalAdmin.sol new file mode 100644 index 0000000..72e9a2b --- /dev/null +++ b/tests/accounts/GlobalAdmin.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity 0.8.7; + +import { User as ProxyUser } from "../../modules/maple-proxy-factory/contracts/test/accounts/User.sol"; + +import { IDebtLocker, IMapleProxied } from "../../contracts/interfaces/IDebtLocker.sol"; + +contract GlobalAdmin is ProxyUser { + + /************************/ + /*** Direct Functions ***/ + /************************/ + + function debtLocker_upgrade(address debtLocker_, uint256 toVersion_, bytes memory arguments_) external { + IDebtLocker(debtLocker_).upgrade(toVersion_, arguments_); + } + + /*********************/ + /*** Try Functions ***/ + /*********************/ + + function try_debtLocker_upgrade(address debtLocker_, uint256 toVersion_, bytes memory arguments_) external returns (bool ok_) { + ( ok_, ) = debtLocker_.call(abi.encodeWithSelector(IMapleProxied.upgrade.selector, toVersion_, arguments_)); + } + +} diff --git a/tests/mocks/DebtLockerHarness.sol b/tests/mocks/DebtLockerHarness.sol index cb9ada3..a5f742b 100644 --- a/tests/mocks/DebtLockerHarness.sol +++ b/tests/mocks/DebtLockerHarness.sol @@ -9,16 +9,16 @@ contract DebtLockerHarness is DebtLocker { /*** Harness Functions ***/ /*************************/ - function getGlobals() external view returns (address) { - return _getGlobals(); + function getGlobals() external view returns (address globals_) { + globals_ = _getGlobals(); } - function getPoolDelegate() external view returns(address) { - return _getPoolDelegate(); + function getPoolDelegate() external view returns(address poolDelegate_) { + poolDelegate_ = _getPoolDelegate(); } - function isLiquidationActive() external view returns (bool) { - return _isLiquidationActive(); + function isLiquidationActive() external view returns (bool isLiquidationActive_) { + isLiquidationActive_ = _isLiquidationActive(); } } diff --git a/tests/mocks/Mocks.sol b/tests/mocks/Mocks.sol index b729991..b1777c3 100644 --- a/tests/mocks/Mocks.sol +++ b/tests/mocks/Mocks.sol @@ -17,8 +17,8 @@ contract MockPoolFactory { globals = globals_; } - function createPool(address poolDelegate_) external returns (address) { - return address(new MockPool(poolDelegate_)); + function createPool(address poolDelegate_) external returns (address pool_) { + pool_ = address(new MockPool(poolDelegate_)); } } @@ -33,16 +33,16 @@ contract MockPool { superFactory = msg.sender; } - function createDebtLocker(address dlFactory, address loan) external returns (address) { - return IDebtLockerFactory(dlFactory).newLocker(loan); + function createDebtLocker(address dlFactory, address loan) external returns (address debtLocker_) { + debtLocker_ = IDebtLockerFactory(dlFactory).newLocker(loan); } - function claim(address debtLocker) external returns (uint256[7] memory) { - return IDebtLocker(debtLocker).claim(); + function claim(address debtLocker) external returns (uint256[7] memory claimInfo_) { + claimInfo_ = IDebtLocker(debtLocker).claim(); } function triggerDefault(address debtLocker) external { - return IDebtLocker(debtLocker).triggerDefault(); + IDebtLocker(debtLocker).triggerDefault(); } } @@ -71,7 +71,7 @@ contract MockLiquidationStrategy { contract MockLoan { function principalRequested() external view returns (uint256 principalRequested_) { - return 0; + principalRequested_ = 0; } function acceptLender() external { @@ -91,6 +91,7 @@ contract MockLoan { contract MockGlobals { address public governor; + address public globalAdmin; mapping(address => bool) public isValidCollateralAsset; mapping(address => bool) public isValidLiquidityAsset; @@ -104,27 +105,31 @@ contract MockGlobals { } function getLatestPrice(address asset_) external view returns (uint256 price_) { - return assetPrices[asset_]; + price_ = assetPrices[asset_]; } function setPrice(address asset_, uint256 price_) external { assetPrices[asset_] = price_; } + function setGlobalAdmin(address newGlobalAdmin_) external { + globalAdmin = newGlobalAdmin_; + } + function setProtocolPause(bool paused_) external { protocolPaused = paused_; } function investorFee() external pure returns (uint256 investorFee_) { - return 50; + investorFee_ = 50; } function treasuryFee() external pure returns (uint256 treasuryFee_) { - return 50; + treasuryFee_ = 50; } function mapleTreasury() external pure returns (address mapleTreasury_) { - return address(1); + mapleTreasury_ = address(1); } function setValidCollateralAsset(address asset_, bool valid_) external {