@gearbox-protocol/periphery-v3 1.3.19 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# Gearbox V3 Periphery
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// SPDX-License-Identifier: UNLICENSED
|
|
2
|
+
// Gearbox Protocol. Generalized leverage for DeFi protocols
|
|
3
|
+
// (c) Gearbox Foundation, 2024.
|
|
4
|
+
pragma solidity ^0.8.17;
|
|
5
|
+
|
|
6
|
+
import {Test} from "forge-std/Test.sol";
|
|
7
|
+
|
|
8
|
+
import {ACL} from "@gearbox-protocol/core-v2/contracts/core/ACL.sol";
|
|
9
|
+
import {ContractsRegister} from "@gearbox-protocol/core-v2/contracts/core/ContractsRegister.sol";
|
|
10
|
+
|
|
11
|
+
import {
|
|
12
|
+
AP_ACL,
|
|
13
|
+
AP_CONTRACTS_REGISTER,
|
|
14
|
+
IAddressProviderV3,
|
|
15
|
+
NO_VERSION_CONTROL
|
|
16
|
+
} from "@gearbox-protocol/core-v3/contracts/interfaces/IAddressProviderV3.sol";
|
|
17
|
+
|
|
18
|
+
abstract contract ForkTest is Test {
|
|
19
|
+
IAddressProviderV3 addressProvider;
|
|
20
|
+
ACL acl;
|
|
21
|
+
ContractsRegister register;
|
|
22
|
+
address configurator;
|
|
23
|
+
|
|
24
|
+
modifier onlyFork() {
|
|
25
|
+
if (address(addressProvider) != address(0)) _;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function _createFork() internal {
|
|
29
|
+
string memory rpcUrl = vm.envOr("FORK_RPC_URL", string(""));
|
|
30
|
+
if (bytes(rpcUrl).length == 0) return;
|
|
31
|
+
|
|
32
|
+
uint256 blockNumber = vm.envOr("FORK_BLOCK_NUMBER", type(uint256).max);
|
|
33
|
+
if (blockNumber == type(uint256).max) {
|
|
34
|
+
vm.createSelectFork(rpcUrl);
|
|
35
|
+
} else {
|
|
36
|
+
vm.createSelectFork(rpcUrl, blockNumber);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
addressProvider = IAddressProviderV3(vm.envAddress("FORK_ADDRESS_PROVIDER"));
|
|
40
|
+
acl = ACL(addressProvider.getAddressOrRevert(AP_ACL, NO_VERSION_CONTROL));
|
|
41
|
+
register = ContractsRegister(addressProvider.getAddressOrRevert(AP_CONTRACTS_REGISTER, NO_VERSION_CONTROL));
|
|
42
|
+
configurator = acl.owner();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// SPDX-License-Identifier: UNLICENSED
|
|
2
|
+
// Gearbox Protocol. Generalized leverage for DeFi protocols
|
|
3
|
+
// (c) Gearbox Foundation, 2024.
|
|
4
|
+
pragma solidity ^0.8.17;
|
|
5
|
+
|
|
6
|
+
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
|
|
7
|
+
import {CallerNotPausableAdminException} from "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol";
|
|
8
|
+
import {ACLNonReentrantTrait} from "@gearbox-protocol/core-v3/contracts/traits/ACLNonReentrantTrait.sol";
|
|
9
|
+
|
|
10
|
+
import {MultiPause} from "../utils/MultiPause.sol";
|
|
11
|
+
|
|
12
|
+
import {ForkTest} from "./ForkTest.sol";
|
|
13
|
+
|
|
14
|
+
contract MultiPauseTest is ForkTest {
|
|
15
|
+
MultiPause multiPause;
|
|
16
|
+
address admin;
|
|
17
|
+
|
|
18
|
+
function setUp() public {
|
|
19
|
+
_createFork();
|
|
20
|
+
|
|
21
|
+
multiPause = new MultiPause(address(addressProvider));
|
|
22
|
+
admin = makeAddr("ADMIN");
|
|
23
|
+
|
|
24
|
+
vm.startPrank(configurator);
|
|
25
|
+
acl.addPausableAdmin(admin);
|
|
26
|
+
acl.addPausableAdmin(address(multiPause));
|
|
27
|
+
vm.stopPrank();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function test_MP_01_functions_revert_if_caller_is_not_pausable_admin() public onlyFork {
|
|
31
|
+
vm.expectRevert(CallerNotPausableAdminException.selector);
|
|
32
|
+
multiPause.pauseContracts(new address[](0));
|
|
33
|
+
|
|
34
|
+
vm.expectRevert(CallerNotPausableAdminException.selector);
|
|
35
|
+
multiPause.pauseAllPools();
|
|
36
|
+
|
|
37
|
+
vm.expectRevert(CallerNotPausableAdminException.selector);
|
|
38
|
+
multiPause.pauseAllCreditManagers();
|
|
39
|
+
|
|
40
|
+
vm.expectRevert(CallerNotPausableAdminException.selector);
|
|
41
|
+
multiPause.pauseAllContracts();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function test_MP_02_pauseContracts_works_as_expected() public onlyFork {
|
|
45
|
+
address[] memory pools = register.getPools();
|
|
46
|
+
|
|
47
|
+
// ensure that at least one contract is paused
|
|
48
|
+
if (!ACLNonReentrantTrait(pools[0]).paused()) {
|
|
49
|
+
vm.prank(admin);
|
|
50
|
+
ACLNonReentrantTrait(pools[0]).pause();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
vm.prank(admin);
|
|
54
|
+
multiPause.pauseContracts(pools);
|
|
55
|
+
|
|
56
|
+
_assert_allPoolsPaused();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function test_MP_03_pauseAllPools_works_as_expected() public onlyFork {
|
|
60
|
+
vm.prank(admin);
|
|
61
|
+
multiPause.pauseAllPools();
|
|
62
|
+
_assert_allPoolsPaused();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function test_MP_04_pauseAllCreditManagers_works_as_expected() public onlyFork {
|
|
66
|
+
vm.prank(admin);
|
|
67
|
+
multiPause.pauseAllCreditManagers();
|
|
68
|
+
_assert_allManagersPaused();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function test_MP_05_pauseAllContracts_works_as_expected() public onlyFork {
|
|
72
|
+
vm.prank(admin);
|
|
73
|
+
multiPause.pauseAllContracts();
|
|
74
|
+
_assert_allPoolsPaused();
|
|
75
|
+
_assert_allManagersPaused();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function _assert_contractsPaused(address[] memory contracts) internal {
|
|
79
|
+
for (uint256 i; i < contracts.length; ++i) {
|
|
80
|
+
assertTrue(
|
|
81
|
+
ACLNonReentrantTrait(contracts[i]).paused(),
|
|
82
|
+
string.concat("Contract ", vm.toString(contracts[i]), " is not paused")
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function _assert_allPoolsPaused() internal {
|
|
88
|
+
address[] memory pools = register.getPools();
|
|
89
|
+
for (uint256 i; i < pools.length; ++i) {
|
|
90
|
+
assertTrue(
|
|
91
|
+
ACLNonReentrantTrait(pools[i]).paused(), string.concat("Pool ", vm.toString(pools[i]), " is not paused")
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function _assert_allManagersPaused() internal {
|
|
97
|
+
address[] memory creditManagers = register.getCreditManagers();
|
|
98
|
+
for (uint256 i; i < creditManagers.length; ++i) {
|
|
99
|
+
if (ICreditManagerV3(creditManagers[i]).version() < 3_00) {
|
|
100
|
+
assertTrue(
|
|
101
|
+
ACLNonReentrantTrait(creditManagers[i]).paused(),
|
|
102
|
+
string.concat("Manager ", vm.toString(creditManagers[i]), " is not paused")
|
|
103
|
+
);
|
|
104
|
+
} else {
|
|
105
|
+
address facade = ICreditManagerV3(creditManagers[i]).creditFacade();
|
|
106
|
+
assertTrue(
|
|
107
|
+
ACLNonReentrantTrait(facade).paused(),
|
|
108
|
+
string.concat("Facade ", vm.toString(facade), " is not paused")
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
2
|
+
// Gearbox Protocol. Generalized leverage for DeFi protocols
|
|
3
|
+
// (c) Gearbox Foundation, 2024.
|
|
4
|
+
pragma solidity ^0.8.17;
|
|
5
|
+
|
|
6
|
+
import {IContractsRegister} from "@gearbox-protocol/core-v2/contracts/interfaces/IContractsRegister.sol";
|
|
7
|
+
|
|
8
|
+
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
|
|
9
|
+
import {ACLNonReentrantTrait} from "@gearbox-protocol/core-v3/contracts/traits/ACLNonReentrantTrait.sol";
|
|
10
|
+
import {ContractsRegisterTrait} from "@gearbox-protocol/core-v3/contracts/traits/ContractsRegisterTrait.sol";
|
|
11
|
+
|
|
12
|
+
/// @title MultiPause
|
|
13
|
+
/// @author Gearbox Foundation
|
|
14
|
+
/// @notice Allows pausable admins to pause multiple contracts in a single transaction
|
|
15
|
+
/// @dev This contract is expected to be one of pausable admins in the ACL contract
|
|
16
|
+
contract MultiPause is ACLNonReentrantTrait, ContractsRegisterTrait {
|
|
17
|
+
constructor(address addressProvider)
|
|
18
|
+
ACLNonReentrantTrait(addressProvider)
|
|
19
|
+
ContractsRegisterTrait(addressProvider)
|
|
20
|
+
{}
|
|
21
|
+
|
|
22
|
+
/// @notice Pauses contracts from the given list
|
|
23
|
+
/// @dev Ignores contracts that are already paused
|
|
24
|
+
/// @dev Reverts if caller is not a pausable admin
|
|
25
|
+
function pauseContracts(address[] memory contracts) external pausableAdminsOnly {
|
|
26
|
+
_pauseContracts(contracts);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/// @notice Pauses all registered pools
|
|
30
|
+
/// @dev Ignores contracts that are already paused
|
|
31
|
+
/// @dev Reverts if caller is not a pausable admin
|
|
32
|
+
function pauseAllPools() external pausableAdminsOnly {
|
|
33
|
+
_pauseAllPools();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// @notice Pauses all registered credit managers
|
|
37
|
+
/// @dev For V3, credit facades are paused instead
|
|
38
|
+
/// @dev Ignores contracts that are already paused
|
|
39
|
+
/// @dev Reverts if caller is not a pausable admin
|
|
40
|
+
function pauseAllCreditManagers() external pausableAdminsOnly {
|
|
41
|
+
_pauseAllCreditManagers();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// @notice Pauses all registered credit managers and pools
|
|
45
|
+
/// @dev Ignores contracts that are already paused
|
|
46
|
+
/// @dev Reverts if caller is not a pausable admin
|
|
47
|
+
function pauseAllContracts() external pausableAdminsOnly {
|
|
48
|
+
_pauseAllPools();
|
|
49
|
+
_pauseAllCreditManagers();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/// @dev Internal function to pause all pools
|
|
53
|
+
function _pauseAllPools() internal {
|
|
54
|
+
_pauseContracts(IContractsRegister(contractsRegister).getPools());
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/// @dev Internal function to pause all credit managers
|
|
58
|
+
function _pauseAllCreditManagers() internal {
|
|
59
|
+
address[] memory contracts = IContractsRegister(contractsRegister).getCreditManagers();
|
|
60
|
+
uint256 len = contracts.length;
|
|
61
|
+
unchecked {
|
|
62
|
+
for (uint256 i; i < len; ++i) {
|
|
63
|
+
if (ICreditManagerV3(contracts[i]).version() < 3_00) continue;
|
|
64
|
+
contracts[i] = ICreditManagerV3(contracts[i]).creditFacade();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
_pauseContracts(contracts);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/// @dev Internal function to pause contracts from the given list
|
|
71
|
+
function _pauseContracts(address[] memory contracts) internal {
|
|
72
|
+
uint256 len = contracts.length;
|
|
73
|
+
unchecked {
|
|
74
|
+
for (uint256 i; i < len; ++i) {
|
|
75
|
+
if (ACLNonReentrantTrait(contracts[i]).paused()) continue;
|
|
76
|
+
ACLNonReentrantTrait(contracts[i]).pause();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
package/package.json
CHANGED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: BUSL-1.1
|
|
2
|
-
// Gearbox Protocol. Generalized leverage for DeFi protocols
|
|
3
|
-
// (c) Gearbox Holdings, 2024
|
|
4
|
-
pragma solidity ^0.8.17;
|
|
5
|
-
|
|
6
|
-
import {ACLNonReentrantTrait} from "@gearbox-protocol/core-v3/contracts/traits/ACLNonReentrantTrait.sol";
|
|
7
|
-
import {
|
|
8
|
-
IAddressProviderV3,
|
|
9
|
-
AP_CONTRACTS_REGISTER,
|
|
10
|
-
NO_VERSION_CONTROL
|
|
11
|
-
} from "@gearbox-protocol/core-v3/contracts/interfaces/IAddressProviderV3.sol";
|
|
12
|
-
import {ContractsRegister} from "@gearbox-protocol/core-v2/contracts/core/ContractsRegister.sol";
|
|
13
|
-
import {
|
|
14
|
-
IAddressProviderV3,
|
|
15
|
-
AP_CONTRACTS_REGISTER
|
|
16
|
-
} from "@gearbox-protocol/core-v3/contracts/interfaces/IAddressProviderV3.sol";
|
|
17
|
-
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
|
|
18
|
-
|
|
19
|
-
contract PauseMulticall is ACLNonReentrantTrait {
|
|
20
|
-
ContractsRegister public immutable cr;
|
|
21
|
-
|
|
22
|
-
constructor(address _addressProvider) ACLNonReentrantTrait(_addressProvider) {
|
|
23
|
-
cr = ContractsRegister(
|
|
24
|
-
IAddressProviderV3(_addressProvider).getAddressOrRevert(AP_CONTRACTS_REGISTER, NO_VERSION_CONTROL)
|
|
25
|
-
); // F: [PM-01]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function pauseAllCreditManagers()
|
|
29
|
-
external
|
|
30
|
-
pausableAdminsOnly // F:[PM-05]
|
|
31
|
-
{
|
|
32
|
-
_pauseAllCreditManagers();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function pauseAllPools()
|
|
36
|
-
external
|
|
37
|
-
pausableAdminsOnly // F:[PM-05]
|
|
38
|
-
{
|
|
39
|
-
_pauseAllPools(); // F: [PM-03]
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function pauseAllContracts()
|
|
43
|
-
external
|
|
44
|
-
pausableAdminsOnly // F:[PM-05]
|
|
45
|
-
{
|
|
46
|
-
_pauseAllPools();
|
|
47
|
-
_pauseAllCreditManagers();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function _pauseAllPools() internal {
|
|
51
|
-
_pauseBatchOfContracts(cr.getPools()); // F: [PM-03]
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function _pauseAllCreditManagers() internal {
|
|
55
|
-
address[] memory allCreditManagers = cr.getCreditManagers();
|
|
56
|
-
|
|
57
|
-
unchecked {
|
|
58
|
-
for (uint256 i = 0; i < allCreditManagers.length; ++i) {
|
|
59
|
-
uint256 version = ICreditManagerV3(allCreditManagers[i]).version();
|
|
60
|
-
if (version >= 3_00) {
|
|
61
|
-
allCreditManagers[i] = ICreditManagerV3(allCreditManagers[i]).creditFacade();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
_pauseBatchOfContracts(allCreditManagers); // F: [PM-04] // F: [PM-02]
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function _pauseBatchOfContracts(address[] memory contractsToPause) internal {
|
|
70
|
-
uint256 len = contractsToPause.length;
|
|
71
|
-
unchecked {
|
|
72
|
-
for (uint256 i = 0; i < len; ++i) {
|
|
73
|
-
// try-catch block to ignore some contracts which are already paused
|
|
74
|
-
try ACLNonReentrantTrait(contractsToPause[i]).pause() {} catch {}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: UNLICENSED
|
|
2
|
-
// Gearbox Protocol. Generalized leverage for DeFi protocols
|
|
3
|
-
// (c) Gearbox Holdings, 2024
|
|
4
|
-
pragma solidity ^0.8.17;
|
|
5
|
-
|
|
6
|
-
import {PauseMulticall} from "../emergency/PauseMulticall.sol";
|
|
7
|
-
import {
|
|
8
|
-
IAddressProviderV3,
|
|
9
|
-
AP_CONTRACTS_REGISTER,
|
|
10
|
-
NO_VERSION_CONTROL
|
|
11
|
-
} from "@gearbox-protocol/core-v3/contracts/interfaces/IAddressProviderV3.sol";
|
|
12
|
-
import {ContractsRegister} from "@gearbox-protocol/core-v2/contracts/core/ContractsRegister.sol";
|
|
13
|
-
import {
|
|
14
|
-
IAddressProviderV3,
|
|
15
|
-
AP_CONTRACTS_REGISTER
|
|
16
|
-
} from "@gearbox-protocol/core-v3/contracts/interfaces/IAddressProviderV3.sol";
|
|
17
|
-
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
|
|
18
|
-
import {NetworkDetector} from "@gearbox-protocol/sdk-gov/contracts/NetworkDetector.sol";
|
|
19
|
-
|
|
20
|
-
import {Test} from "forge-std/Test.sol";
|
|
21
|
-
import "forge-std/console.sol";
|
|
22
|
-
|
|
23
|
-
address constant ap = 0x9ea7b04Da02a5373317D745c1571c84aaD03321D;
|
|
24
|
-
|
|
25
|
-
contract PauseMulticallTest is Test {
|
|
26
|
-
uint256 chainId;
|
|
27
|
-
|
|
28
|
-
PauseMulticall pm;
|
|
29
|
-
|
|
30
|
-
constructor() {
|
|
31
|
-
NetworkDetector nd = new NetworkDetector();
|
|
32
|
-
chainId = nd.chainId();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
modifier liveTestOnly() {
|
|
36
|
-
if (chainId == 1) {
|
|
37
|
-
_;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function setUp() public liveTestOnly {
|
|
42
|
-
pm = new PauseMulticall(ap);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
///
|
|
46
|
-
/// TESTS
|
|
47
|
-
///
|
|
48
|
-
}
|