@gearbox-protocol/periphery-v3 1.7.0-next.17 → 1.7.0-next.19
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/contracts/compressors/AdapterCompressor.sol +7 -7
- package/contracts/compressors/CreditAccountCompressor.sol +11 -13
- package/contracts/compressors/MarketCompressor.sol +113 -0
- package/contracts/compressors/PriceFeedCompressor.sol +1 -0
- package/contracts/data/DataCompressorV3.sol +2 -1
- package/contracts/data/ZapperRegister.sol +9 -7
- package/contracts/emergency/MultiPause.sol +19 -11
- package/contracts/interfaces/ICreditAccountCompressor.sol +60 -0
- package/contracts/interfaces/IMarketCompressor.sol +11 -0
- package/contracts/libraries/Contains.sol +15 -0
- package/contracts/serializers/oracles/LPPriceFeedSerializer.sol +2 -2
- package/contracts/test/ForkTest.sol +3 -3
- package/contracts/test/MultiPause.t.sol +12 -18
- package/contracts/test/interfaces/IACLExt.sol +1 -1
- package/contracts/test/interfaces/IContractsRegisterExt.sol +1 -1
- package/package.json +3 -7
- package/contracts/compressors/MarketCompressorV3.sol +0 -68
- /package/contracts/{compressors/Types.sol → types/CreditAccountState.sol} +0 -0
|
@@ -31,13 +31,13 @@ contract AdaptgerCompressorV3 {
|
|
|
31
31
|
|
|
32
32
|
/// add try{} catch for serialisation
|
|
33
33
|
|
|
34
|
-
adapters[i] = ContractAdapter({
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
});
|
|
34
|
+
// adapters[i] = ContractAdapter({
|
|
35
|
+
// targetContract: ICreditManagerV3(creditManager).adapterToContract(allowedAdapter),
|
|
36
|
+
// adapter: allowedAdapter,
|
|
37
|
+
// adapterType: uint8(IAdapter(allowedAdapter)._gearboxAdapterType()),
|
|
38
|
+
// version: IAdapter(allowedAdapter)._gearboxAdapterVersion(),
|
|
39
|
+
// stateSerialised: stateSerialised
|
|
40
|
+
// });
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -6,7 +6,7 @@ pragma solidity ^0.8.17;
|
|
|
6
6
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
7
7
|
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
|
|
8
8
|
|
|
9
|
-
import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/IContractsRegister.sol";
|
|
9
|
+
import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IContractsRegister.sol";
|
|
10
10
|
import {ICreditAccountV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditAccountV3.sol";
|
|
11
11
|
import {
|
|
12
12
|
CollateralCalcTask,
|
|
@@ -17,19 +17,25 @@ import {IPoolQuotaKeeperV3} from "@gearbox-protocol/core-v3/contracts/interfaces
|
|
|
17
17
|
import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
|
|
18
18
|
import {PERCENTAGE_FACTOR} from "@gearbox-protocol/core-v3/contracts/libraries/Constants.sol";
|
|
19
19
|
import {SanityCheckTrait} from "@gearbox-protocol/core-v3/contracts/traits/SanityCheckTrait.sol";
|
|
20
|
+
import {ICreditAccountCompressor} from "../interfaces/ICreditAccountCompressor.sol";
|
|
20
21
|
|
|
21
22
|
import {IAddressProviderV3} from "@gearbox-protocol/governance/contracts/interfaces/IAddressProviderV3.sol";
|
|
22
23
|
import {IMarketConfiguratorV3} from "@gearbox-protocol/governance/contracts/interfaces/IMarketConfiguratorV3.sol";
|
|
23
24
|
|
|
24
|
-
import {CreditAccountData, CreditAccountFilter, CreditManagerFilter, TokenInfo} from "
|
|
25
|
+
import {CreditAccountData, CreditAccountFilter, CreditManagerFilter, TokenInfo} from "../types/CreditAccountState.sol";
|
|
26
|
+
|
|
27
|
+
import {Contains} from "../libraries/Contains.sol";
|
|
25
28
|
|
|
26
29
|
/// @title Credit account compressor
|
|
27
30
|
/// @notice Allows to fetch data on all credit accounts matching certain criteria in an efficient manner
|
|
28
31
|
/// @dev The contract is not gas optimized and is thus not recommended for on-chain use
|
|
29
32
|
/// @dev Querying functions try to process as many accounts as possible and stop when they get close to gas limit
|
|
30
|
-
contract CreditAccountCompressor is
|
|
33
|
+
contract CreditAccountCompressor is ICreditAccountCompressor, SanityCheckTrait {
|
|
34
|
+
using Contains for address[];
|
|
35
|
+
|
|
31
36
|
/// @notice Contract version
|
|
32
37
|
uint256 public constant override version = 3_10;
|
|
38
|
+
bytes32 public constant override contractType = "CREDIT_ACCOUNT_COMPRESSOR";
|
|
33
39
|
|
|
34
40
|
/// @notice Address provider contract address
|
|
35
41
|
address public immutable ADDRESS_PROVIDER;
|
|
@@ -372,7 +378,7 @@ contract CreditAccountCompressor is IVersion, SanityCheckTrait {
|
|
|
372
378
|
uint256 num;
|
|
373
379
|
for (uint256 i; i < configurators.length; ++i) {
|
|
374
380
|
if (filter.curators.length != 0) {
|
|
375
|
-
if (!
|
|
381
|
+
if (!filter.curators.contains(IMarketConfiguratorV3(configurators[i]).owner())) continue;
|
|
376
382
|
}
|
|
377
383
|
|
|
378
384
|
address cr = IMarketConfiguratorV3(configurators[i]).contractsRegister();
|
|
@@ -383,7 +389,7 @@ contract CreditAccountCompressor is IVersion, SanityCheckTrait {
|
|
|
383
389
|
if (ver < 3_00 || ver > 3_99) continue;
|
|
384
390
|
|
|
385
391
|
if (filter.pools.length != 0) {
|
|
386
|
-
if (!
|
|
392
|
+
if (!filter.pools.contains(ICreditManagerV3(managers[j]).pool())) continue;
|
|
387
393
|
}
|
|
388
394
|
|
|
389
395
|
if (filter.underlying != address(0)) {
|
|
@@ -399,12 +405,4 @@ contract CreditAccountCompressor is IVersion, SanityCheckTrait {
|
|
|
399
405
|
mstore(creditManagers, num)
|
|
400
406
|
}
|
|
401
407
|
}
|
|
402
|
-
|
|
403
|
-
/// @dev Checks whether `arr` contains `value`
|
|
404
|
-
function _contains(address[] memory arr, address value) internal pure returns (bool) {
|
|
405
|
-
for (uint256 i; i < arr.length; ++i) {
|
|
406
|
-
if (value == arr[i]) return true;
|
|
407
|
-
}
|
|
408
|
-
return false;
|
|
409
|
-
}
|
|
410
408
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Gearbox Protocol. Generalized leverage for DeFi protocols
|
|
3
|
+
// (c) Gearbox Holdings, 2024
|
|
4
|
+
pragma solidity ^0.8.17;
|
|
5
|
+
|
|
6
|
+
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
|
|
7
|
+
import {IPoolQuotaKeeperV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolQuotaKeeperV3.sol";
|
|
8
|
+
import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IContractsRegister.sol";
|
|
9
|
+
import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
|
|
10
|
+
|
|
11
|
+
import {Contains} from "../libraries/Contains.sol";
|
|
12
|
+
|
|
13
|
+
import {IAddressProviderV3} from "@gearbox-protocol/governance/contracts/interfaces/IAddressProviderV3.sol";
|
|
14
|
+
import {IMarketConfiguratorV3} from "@gearbox-protocol/governance/contracts/interfaces/IMarketConfiguratorV3.sol";
|
|
15
|
+
|
|
16
|
+
import {PoolCompressorV3} from "./PoolCompressor.sol";
|
|
17
|
+
import {PriceFeedCompressor} from "./PriceFeedCompressor.sol";
|
|
18
|
+
|
|
19
|
+
// // EXCEPTIONS
|
|
20
|
+
// import "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol";
|
|
21
|
+
|
|
22
|
+
import {MarketData} from "../types/MarketData.sol";
|
|
23
|
+
import {PoolState} from "../types/PoolState.sol";
|
|
24
|
+
|
|
25
|
+
import {IMarketCompressor} from "../interfaces/IMarketCompressor.sol";
|
|
26
|
+
|
|
27
|
+
import "forge-std/console.sol";
|
|
28
|
+
|
|
29
|
+
/// @title Data compressor 3.0.
|
|
30
|
+
/// @notice Collects data from various contracts for use in the dApp
|
|
31
|
+
/// Do not use for data from data compressor for state-changing functions
|
|
32
|
+
contract MarketCompressor is IMarketCompressor {
|
|
33
|
+
using Contains for address[];
|
|
34
|
+
// Contract version
|
|
35
|
+
|
|
36
|
+
uint256 public constant version = 3_10;
|
|
37
|
+
bytes32 public constant contractType = "MARKET_COMPRESSOR";
|
|
38
|
+
|
|
39
|
+
/// @notice Address provider contract address
|
|
40
|
+
address public immutable ADDRESS_PROVIDER;
|
|
41
|
+
|
|
42
|
+
PriceFeedCompressor priceOracleCompressor;
|
|
43
|
+
PoolCompressorV3 poolCompressor;
|
|
44
|
+
|
|
45
|
+
error CreditManagerIsNotV3Exception();
|
|
46
|
+
|
|
47
|
+
constructor(address addressProvider, address priceOracleCompressorAddress) {
|
|
48
|
+
ADDRESS_PROVIDER = addressProvider;
|
|
49
|
+
addressProvider = addressProvider;
|
|
50
|
+
poolCompressor = new PoolCompressorV3();
|
|
51
|
+
priceOracleCompressor = PriceFeedCompressor(priceOracleCompressorAddress);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getMarketData(address pool) public view returns (MarketData memory result) {
|
|
55
|
+
result.pool = poolCompressor.getPoolState(pool);
|
|
56
|
+
result.poolQuotaKeeper = poolCompressor.getPoolQuotaKeeperState(result.pool.poolQuotaKeeper);
|
|
57
|
+
result.rateKeeper = poolCompressor.getRateKeeperState(result.poolQuotaKeeper.rateKeeper);
|
|
58
|
+
result.interestRateModel = poolCompressor.getInterestRateModelState(result.pool.interestRateModel);
|
|
59
|
+
|
|
60
|
+
address priceOracle = _getPriceOracle(result.pool);
|
|
61
|
+
address[] memory tokens = IPoolQuotaKeeperV3(result.pool.poolQuotaKeeper).quotedTokens();
|
|
62
|
+
|
|
63
|
+
result.tokens = new address[](tokens.length + 1);
|
|
64
|
+
result.tokens[0] = result.pool.underlying;
|
|
65
|
+
|
|
66
|
+
for (uint256 i = 0; i < tokens.length; i++) {
|
|
67
|
+
result.tokens[i + 1] = tokens[i];
|
|
68
|
+
}
|
|
69
|
+
// How to query if no credit mangers are deployed?
|
|
70
|
+
result.priceOracleData = priceOracleCompressor.getPriceOracleState(priceOracle, result.tokens);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function _getPriceOracle(PoolState memory ps) internal view returns (address) {
|
|
74
|
+
if (ps.creditManagerDebtParams.length == 0) {
|
|
75
|
+
return address(0);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return ICreditManagerV3(ps.creditManagerDebtParams[0].creditManager).priceOracle();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/// @dev Credit managers discovery
|
|
82
|
+
function _getPools(address[] memory riskCurators) internal view returns (address[] memory pools) {
|
|
83
|
+
address[] memory configurators = IAddressProviderV3(ADDRESS_PROVIDER).marketConfigurators();
|
|
84
|
+
|
|
85
|
+
// rough estimate of maximum number of credit managers
|
|
86
|
+
uint256 max;
|
|
87
|
+
for (uint256 i; i < configurators.length; ++i) {
|
|
88
|
+
if (riskCurators.contains(IMarketConfiguratorV3(configurators[i]).owner())) {
|
|
89
|
+
address cr = IMarketConfiguratorV3(configurators[i]).contractsRegister();
|
|
90
|
+
max += IContractsRegister(cr).getCreditManagers().length;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// allocate the array with maximum potentially needed size (total number of credit managers can be assumed
|
|
95
|
+
// to be relatively small and the function is only called once, so memory expansion cost is not an issue)
|
|
96
|
+
pools = new address[](max);
|
|
97
|
+
uint256 num;
|
|
98
|
+
|
|
99
|
+
for (uint256 i; i < configurators.length; ++i) {
|
|
100
|
+
if (riskCurators.contains(IMarketConfiguratorV3(configurators[i]).owner())) {
|
|
101
|
+
address cr = IMarketConfiguratorV3(configurators[i]).contractsRegister();
|
|
102
|
+
address[] memory managers = IContractsRegister(cr).getPools();
|
|
103
|
+
for (uint256 j; j < managers.length; ++j) {
|
|
104
|
+
// we're only concerned with v3 contracts
|
|
105
|
+
uint256 ver = IVersion(managers[j]).version();
|
|
106
|
+
if (ver < 3_00 || ver > 3_99) continue;
|
|
107
|
+
|
|
108
|
+
pools[num++] = managers[j];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -41,6 +41,7 @@ contract PriceFeedCompressor is IPriceFeedCompressor {
|
|
|
41
41
|
|
|
42
42
|
/// @notice Contract version
|
|
43
43
|
uint256 public constant override version = 3_10;
|
|
44
|
+
bytes32 public constant override contractType = "PRICE_FEED_COMPRESSOR";
|
|
44
45
|
|
|
45
46
|
/// @notice Map of state serializers for different price feed types
|
|
46
47
|
/// @dev Serializers only apply to feeds that don't implement `IStateSerializer` themselves
|
|
@@ -10,7 +10,7 @@ import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol";
|
|
|
10
10
|
import {PERCENTAGE_FACTOR, RAY} from "@gearbox-protocol/core-v3/contracts/libraries/Constants.sol";
|
|
11
11
|
|
|
12
12
|
import {ContractsRegisterTrait} from "@gearbox-protocol/core-v3/contracts/traits/ContractsRegisterTrait.sol";
|
|
13
|
-
import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/IContractsRegister.sol";
|
|
13
|
+
import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IContractsRegister.sol";
|
|
14
14
|
import {CreditFacadeV3} from "@gearbox-protocol/core-v3/contracts/credit/CreditFacadeV3.sol";
|
|
15
15
|
|
|
16
16
|
import {
|
|
@@ -64,6 +64,7 @@ import {IZapperRegister} from "../interfaces/IZapperRegister.sol";
|
|
|
64
64
|
contract DataCompressorV3 is IDataCompressorV3, ContractsRegisterTrait {
|
|
65
65
|
// Contract version
|
|
66
66
|
uint256 public constant version = 3_00;
|
|
67
|
+
bytes32 public constant contractType = "DATA_COMPRESSOR";
|
|
67
68
|
|
|
68
69
|
IZapperRegister public zapperRegister;
|
|
69
70
|
|
|
@@ -6,10 +6,12 @@ pragma solidity ^0.8.10;
|
|
|
6
6
|
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
|
|
7
7
|
import {IZapper} from "@gearbox-protocol/integrations-v3/contracts/interfaces/zappers/IZapper.sol";
|
|
8
8
|
import {IZapperRegister} from "../interfaces/IZapperRegister.sol";
|
|
9
|
-
import {
|
|
9
|
+
import {ACLTrait} from "@gearbox-protocol/core-v3/contracts/traits/ACLTrait.sol";
|
|
10
10
|
import {ContractsRegisterTrait} from "@gearbox-protocol/core-v3/contracts/traits/ContractsRegisterTrait.sol";
|
|
11
|
+
import {SanityCheckTrait} from "@gearbox-protocol/core-v3/contracts/traits/SanityCheckTrait.sol";
|
|
12
|
+
import {ControlledTrait} from "@gearbox-protocol/core-v3/contracts/traits/ControlledTrait.sol";
|
|
11
13
|
|
|
12
|
-
contract ZapperRegister is
|
|
14
|
+
contract ZapperRegister is ContractsRegisterTrait, SanityCheckTrait, ControlledTrait, IZapperRegister {
|
|
13
15
|
using EnumerableSet for EnumerableSet.AddressSet;
|
|
14
16
|
|
|
15
17
|
// Contract version
|
|
@@ -17,12 +19,12 @@ contract ZapperRegister is ACLNonReentrantTrait, ContractsRegisterTrait, IZapper
|
|
|
17
19
|
|
|
18
20
|
mapping(address => EnumerableSet.AddressSet) internal _zappersMap;
|
|
19
21
|
|
|
20
|
-
constructor(address
|
|
21
|
-
|
|
22
|
-
ContractsRegisterTrait(
|
|
22
|
+
constructor(address acl, address contractsRegister)
|
|
23
|
+
ControlledTrait(acl)
|
|
24
|
+
ContractsRegisterTrait(contractsRegister)
|
|
23
25
|
{}
|
|
24
26
|
|
|
25
|
-
function addZapper(address zapper) external nonZeroAddress(zapper)
|
|
27
|
+
function addZapper(address zapper) external nonZeroAddress(zapper) controllerOrConfiguratorOnly {
|
|
26
28
|
address pool = IZapper(zapper).pool();
|
|
27
29
|
_ensureRegisteredPool(pool);
|
|
28
30
|
|
|
@@ -33,7 +35,7 @@ contract ZapperRegister is ACLNonReentrantTrait, ContractsRegisterTrait, IZapper
|
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
function removeZapper(address zapper) external nonZeroAddress(zapper)
|
|
38
|
+
function removeZapper(address zapper) external nonZeroAddress(zapper) controllerOrConfiguratorOnly {
|
|
37
39
|
EnumerableSet.AddressSet storage zapperSet = _zappersMap[IZapper(zapper).pool()];
|
|
38
40
|
if (zapperSet.contains(zapper)) {
|
|
39
41
|
zapperSet.remove(zapper);
|
|
@@ -4,24 +4,32 @@
|
|
|
4
4
|
pragma solidity ^0.8.17;
|
|
5
5
|
|
|
6
6
|
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
|
|
7
|
-
import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/IContractsRegister.sol";
|
|
8
|
-
import {
|
|
7
|
+
import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IContractsRegister.sol";
|
|
8
|
+
import {ACLTrait} from "@gearbox-protocol/core-v3/contracts/traits/ACLTrait.sol";
|
|
9
9
|
import {ContractsRegisterTrait} from "@gearbox-protocol/core-v3/contracts/traits/ContractsRegisterTrait.sol";
|
|
10
|
+
import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol";
|
|
10
11
|
|
|
11
12
|
enum PausableAction {
|
|
12
13
|
Pause,
|
|
13
14
|
Unpause
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
interface PausableContract {
|
|
18
|
+
/// @notice Pauses contract, can only be called by an account with pausable admin role
|
|
19
|
+
/// @dev Reverts if contract is already paused
|
|
20
|
+
function pause() external;
|
|
21
|
+
|
|
22
|
+
/// @notice Unpauses contract, can only be called by an account with unpausable admin role
|
|
23
|
+
/// @dev Reverts if contract is already unpaused
|
|
24
|
+
function unpause() external;
|
|
25
|
+
}
|
|
26
|
+
|
|
16
27
|
/// @title MultiPause
|
|
17
28
|
/// @author Gearbox Foundation
|
|
18
29
|
/// @notice Allows pausable admins to pause multiple contracts in a single transaction
|
|
19
30
|
/// @dev This contract is expected to be one of pausable admins in the ACL contract
|
|
20
|
-
contract MultiPause is
|
|
21
|
-
constructor(address acl_, address contractsRegister_)
|
|
22
|
-
ACLNonReentrantTrait(acl_)
|
|
23
|
-
ContractsRegisterTrait(contractsRegister_)
|
|
24
|
-
{}
|
|
31
|
+
contract MultiPause is ACLTrait, ContractsRegisterTrait {
|
|
32
|
+
constructor(address acl_, address contractsRegister_) ACLTrait(acl_) ContractsRegisterTrait(contractsRegister_) {}
|
|
25
33
|
|
|
26
34
|
/// @notice Pauses contracts from the given list
|
|
27
35
|
/// @dev Ignores contracts that are already paused
|
|
@@ -85,11 +93,11 @@ contract MultiPause is ACLNonReentrantTrait, ContractsRegisterTrait {
|
|
|
85
93
|
unchecked {
|
|
86
94
|
for (uint256 i; i < len; ++i) {
|
|
87
95
|
if (action == PausableAction.Pause) {
|
|
88
|
-
if (
|
|
89
|
-
|
|
96
|
+
if (Pausable(contracts[i]).paused()) continue;
|
|
97
|
+
PausableContract(contracts[i]).pause();
|
|
90
98
|
} else {
|
|
91
|
-
if (!
|
|
92
|
-
|
|
99
|
+
if (!Pausable(contracts[i]).paused()) continue;
|
|
100
|
+
PausableContract(contracts[i]).unpause();
|
|
93
101
|
}
|
|
94
102
|
}
|
|
95
103
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Gearbox Protocol. Generalized leverage for DeFi protocols
|
|
3
|
+
// (c) Gearbox Foundation, 2024.
|
|
4
|
+
pragma solidity ^0.8.17;
|
|
5
|
+
|
|
6
|
+
import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
|
|
7
|
+
import {CreditAccountData, CreditAccountFilter, CreditManagerFilter, TokenInfo} from "../types/CreditAccountState.sol";
|
|
8
|
+
|
|
9
|
+
/// @title Credit account compressor
|
|
10
|
+
/// @notice Allows to fetch data on all credit accounts matching certain criteria in an efficient manner
|
|
11
|
+
/// @dev The contract is not gas optimized and is thus not recommended for on-chain use
|
|
12
|
+
/// @dev Querying functions try to process as many accounts as possible and stop when they get close to gas limit
|
|
13
|
+
interface ICreditAccountCompressor is IVersion {
|
|
14
|
+
/// @notice Returns data for a particular `creditAccount`
|
|
15
|
+
function getCreditAccountData(address creditAccount) external view returns (CreditAccountData memory);
|
|
16
|
+
|
|
17
|
+
/// @notice Returns data for credit accounts that match `caFilter` in credit managers matching `cmFilter`
|
|
18
|
+
/// @dev The non-zero value of `nextOffset` return variable indicates that gas supplied with a call was
|
|
19
|
+
/// insufficient to process all the accounts and next iteration starting from this value is needed
|
|
20
|
+
function getCreditAccounts(CreditManagerFilter memory cmFilter, CreditAccountFilter memory caFilter, uint256 offset)
|
|
21
|
+
external
|
|
22
|
+
view
|
|
23
|
+
returns (CreditAccountData[] memory data, uint256 nextOffset);
|
|
24
|
+
|
|
25
|
+
/// @dev Same as above but with `limit` parameter that specifies the number of accounts to process
|
|
26
|
+
function getCreditAccounts(
|
|
27
|
+
CreditManagerFilter memory cmFilter,
|
|
28
|
+
CreditAccountFilter memory caFilter,
|
|
29
|
+
uint256 offset,
|
|
30
|
+
uint256 limit
|
|
31
|
+
) external view returns (CreditAccountData[] memory data, uint256 nextOffset);
|
|
32
|
+
|
|
33
|
+
/// @notice Returns data for credit accounts that match `caFilter` in a given `creditManager`
|
|
34
|
+
/// @dev The non-zero value of `nextOffset` return variable indicates that gas supplied with a call was
|
|
35
|
+
/// insufficient to process all the accounts and next iteration starting from this value is needed
|
|
36
|
+
function getCreditAccounts(address creditManager, CreditAccountFilter memory caFilter, uint256 offset)
|
|
37
|
+
external
|
|
38
|
+
view
|
|
39
|
+
returns (CreditAccountData[] memory data, uint256 nextOffset);
|
|
40
|
+
|
|
41
|
+
/// @dev Same as above but with `limit` parameter that specifies the number of accounts to process
|
|
42
|
+
function getCreditAccounts(
|
|
43
|
+
address creditManager,
|
|
44
|
+
CreditAccountFilter memory caFilter,
|
|
45
|
+
uint256 offset,
|
|
46
|
+
uint256 limit
|
|
47
|
+
) external view returns (CreditAccountData[] memory data, uint256 nextOffset);
|
|
48
|
+
|
|
49
|
+
/// @notice Counts credit accounts that match `caFilter` in credit managers matching `cmFilter`
|
|
50
|
+
function countCreditAccounts(CreditManagerFilter memory cmFilter, CreditAccountFilter memory caFilter)
|
|
51
|
+
external
|
|
52
|
+
view
|
|
53
|
+
returns (uint256);
|
|
54
|
+
|
|
55
|
+
/// @notice Counts credit accounts that match `caFilter` in a given `creditManager`
|
|
56
|
+
function countCreditAccounts(address creditManager, CreditAccountFilter memory caFilter)
|
|
57
|
+
external
|
|
58
|
+
view
|
|
59
|
+
returns (uint256);
|
|
60
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {MarketData} from "../types/MarketData.sol";
|
|
2
|
+
import {PoolState} from "../types/PoolState.sol";
|
|
3
|
+
import {IVersion} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IVersion.sol";
|
|
4
|
+
import "forge-std/console.sol";
|
|
5
|
+
|
|
6
|
+
/// @title Data compressor 3.0.
|
|
7
|
+
/// @notice Collects data from various contracts for use in the dApp
|
|
8
|
+
/// Do not use for data from data compressor for state-changing functions
|
|
9
|
+
interface IMarketCompressor is IVersion {
|
|
10
|
+
function getMarketData(address pool) external view returns (MarketData memory result);
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Gearbox Protocol. Generalized leverage for DeFi protocols
|
|
3
|
+
// (c) Gearbox Foundation, 2024.
|
|
4
|
+
pragma solidity ^0.8.17;
|
|
5
|
+
|
|
6
|
+
library Contains {
|
|
7
|
+
function contains(address[] memory array, address element) internal pure returns (bool) {
|
|
8
|
+
for (uint256 i = 0; i < array.length; i++) {
|
|
9
|
+
if (array[i] == element) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -23,8 +23,8 @@ contract LPPriceFeedSerializer is IStateSerializerLegacy {
|
|
|
23
23
|
pf.lpContract(),
|
|
24
24
|
pf.lowerBound(),
|
|
25
25
|
pf.upperBound(),
|
|
26
|
-
pf.updateBoundsAllowed(),
|
|
27
|
-
pf.lastBoundsUpdate(),
|
|
26
|
+
// pf.updateBoundsAllowed(),
|
|
27
|
+
// pf.lastBoundsUpdate(),
|
|
28
28
|
_getPriceData(pf)
|
|
29
29
|
);
|
|
30
30
|
}
|
|
@@ -12,12 +12,12 @@ import {
|
|
|
12
12
|
NO_VERSION_CONTROL
|
|
13
13
|
} from "@gearbox-protocol/core-v3/contracts/test/interfaces/IAddressProviderV3.sol";
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import {ACL} from "@gearbox-protocol/governance/contracts/market/ACL.sol";
|
|
16
16
|
import {IContractsRegisterExt} from "./interfaces/IContractsRegisterExt.sol";
|
|
17
17
|
|
|
18
18
|
abstract contract ForkTest is Test {
|
|
19
19
|
IAddressProviderV3 addressProvider;
|
|
20
|
-
|
|
20
|
+
ACL acl;
|
|
21
21
|
IContractsRegisterExt register;
|
|
22
22
|
address configurator;
|
|
23
23
|
|
|
@@ -37,7 +37,7 @@ abstract contract ForkTest is Test {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
addressProvider = IAddressProviderV3(vm.envAddress("FORK_ADDRESS_PROVIDER"));
|
|
40
|
-
acl =
|
|
40
|
+
acl = ACL(addressProvider.getAddressOrRevert(AP_ACL, NO_VERSION_CONTROL));
|
|
41
41
|
register = IContractsRegisterExt(addressProvider.getAddressOrRevert(AP_CONTRACTS_REGISTER, NO_VERSION_CONTROL));
|
|
42
42
|
configurator = acl.owner();
|
|
43
43
|
}
|
|
@@ -5,9 +5,9 @@ pragma solidity ^0.8.17;
|
|
|
5
5
|
|
|
6
6
|
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
|
|
7
7
|
import {CallerNotPausableAdminException} from "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
import {
|
|
8
|
+
import {ACLTrait} from "@gearbox-protocol/core-v3/contracts/traits/ACLTrait.sol";
|
|
9
|
+
import {MultiPause, PausableContract} from "../emergency/MultiPause.sol";
|
|
10
|
+
import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol";
|
|
11
11
|
|
|
12
12
|
import {ForkTest} from "./ForkTest.sol";
|
|
13
13
|
|
|
@@ -45,9 +45,9 @@ contract MultiPauseTest is ForkTest {
|
|
|
45
45
|
address[] memory pools = register.getPools();
|
|
46
46
|
|
|
47
47
|
// ensure that at least one contract is paused
|
|
48
|
-
if (!
|
|
48
|
+
if (!Pausable(pools[0]).paused()) {
|
|
49
49
|
vm.prank(admin);
|
|
50
|
-
|
|
50
|
+
PausableContract(pools[0]).pause();
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
vm.prank(admin);
|
|
@@ -75,38 +75,32 @@ contract MultiPauseTest is ForkTest {
|
|
|
75
75
|
_assert_allManagersPaused();
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
function _assert_contractsPaused(address[] memory contracts) internal {
|
|
78
|
+
function _assert_contractsPaused(address[] memory contracts) internal view {
|
|
79
79
|
for (uint256 i; i < contracts.length; ++i) {
|
|
80
80
|
assertTrue(
|
|
81
|
-
|
|
82
|
-
string.concat("Contract ", vm.toString(contracts[i]), " is not paused")
|
|
81
|
+
Pausable(contracts[i]).paused(), string.concat("Contract ", vm.toString(contracts[i]), " is not paused")
|
|
83
82
|
);
|
|
84
83
|
}
|
|
85
84
|
}
|
|
86
85
|
|
|
87
|
-
function _assert_allPoolsPaused() internal {
|
|
86
|
+
function _assert_allPoolsPaused() internal view {
|
|
88
87
|
address[] memory pools = register.getPools();
|
|
89
88
|
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
|
-
);
|
|
89
|
+
assertTrue(Pausable(pools[i]).paused(), string.concat("Pool ", vm.toString(pools[i]), " is not paused"));
|
|
93
90
|
}
|
|
94
91
|
}
|
|
95
92
|
|
|
96
|
-
function _assert_allManagersPaused() internal {
|
|
93
|
+
function _assert_allManagersPaused() internal view {
|
|
97
94
|
address[] memory creditManagers = register.getCreditManagers();
|
|
98
95
|
for (uint256 i; i < creditManagers.length; ++i) {
|
|
99
96
|
if (ICreditManagerV3(creditManagers[i]).version() < 3_00) {
|
|
100
97
|
assertTrue(
|
|
101
|
-
|
|
98
|
+
Pausable(creditManagers[i]).paused(),
|
|
102
99
|
string.concat("Manager ", vm.toString(creditManagers[i]), " is not paused")
|
|
103
100
|
);
|
|
104
101
|
} else {
|
|
105
102
|
address facade = ICreditManagerV3(creditManagers[i]).creditFacade();
|
|
106
|
-
assertTrue(
|
|
107
|
-
ACLNonReentrantTrait(facade).paused(),
|
|
108
|
-
string.concat("Facade ", vm.toString(facade), " is not paused")
|
|
109
|
-
);
|
|
103
|
+
assertTrue(Pausable(facade).paused(), string.concat("Facade ", vm.toString(facade), " is not paused"));
|
|
110
104
|
}
|
|
111
105
|
}
|
|
112
106
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// (c) Gearbox Foundation, 2024.
|
|
4
4
|
pragma solidity ^0.8.17;
|
|
5
5
|
|
|
6
|
-
import {IACL} from "@gearbox-protocol/core-v3/contracts/interfaces/IACL.sol";
|
|
6
|
+
import {IACL} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IACL.sol";
|
|
7
7
|
|
|
8
8
|
interface IACLExt is IACL {
|
|
9
9
|
function addPausableAdmin(address addr) external;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// (c) Gearbox Foundation, 2024.
|
|
4
4
|
pragma solidity ^0.8.17;
|
|
5
5
|
|
|
6
|
-
import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/IContractsRegister.sol";
|
|
6
|
+
import {IContractsRegister} from "@gearbox-protocol/core-v3/contracts/interfaces/base/IContractsRegister.sol";
|
|
7
7
|
|
|
8
8
|
interface IContractsRegisterExt is IContractsRegister {
|
|
9
9
|
function addPool(address pool) external;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gearbox-protocol/periphery-v3",
|
|
3
|
-
"version": "1.7.0-next.
|
|
3
|
+
"version": "1.7.0-next.19",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"repository": "git@github.com:Gearbox-protocol/periphery-v3.git",
|
|
6
6
|
"author": "Mikael <26343374+0xmikko@users.noreply.github.com>",
|
|
@@ -18,13 +18,9 @@
|
|
|
18
18
|
"@chainlink/contracts": "^0.4.0",
|
|
19
19
|
"@commitlint/cli": "^17.6.3",
|
|
20
20
|
"@commitlint/config-conventional": "17.6.0",
|
|
21
|
-
"@gearbox-protocol/
|
|
22
|
-
"@gearbox-protocol/governance": "^1.4.0-next.5",
|
|
23
|
-
"@gearbox-protocol/integrations-v3": "^1.23.1",
|
|
24
|
-
"@gearbox-protocol/oracles-v3": "^1.11.0-next.3",
|
|
25
|
-
"@gearbox-protocol/sdk-gov": "^2.17.0",
|
|
21
|
+
"@gearbox-protocol/sdk-gov": "^2.18.2",
|
|
26
22
|
"@openzeppelin/contracts": "^4.9.3",
|
|
27
|
-
"@redstone-finance/evm-connector": "0.
|
|
23
|
+
"@redstone-finance/evm-connector": "^0.6.1",
|
|
28
24
|
"ds-test": "dapphub/ds-test",
|
|
29
25
|
"forge-std": "foundry-rs/forge-std"
|
|
30
26
|
},
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
// Gearbox Protocol. Generalized leverage for DeFi protocols
|
|
3
|
-
// (c) Gearbox Holdings, 2024
|
|
4
|
-
pragma solidity ^0.8.17;
|
|
5
|
-
|
|
6
|
-
import {ICreditManagerV3} from "@gearbox-protocol/core-v3/contracts/interfaces/ICreditManagerV3.sol";
|
|
7
|
-
import {IPoolQuotaKeeperV3} from "@gearbox-protocol/core-v3/contracts/interfaces/IPoolQuotaKeeperV3.sol";
|
|
8
|
-
|
|
9
|
-
import {PoolCompressorV3} from "./PoolCompressor.sol";
|
|
10
|
-
import {PriceFeedCompressor} from "./PriceFeedCompressor.sol";
|
|
11
|
-
|
|
12
|
-
// // EXCEPTIONS
|
|
13
|
-
// import "@gearbox-protocol/core-v3/contracts/interfaces/IExceptions.sol";
|
|
14
|
-
|
|
15
|
-
import {MarketData} from "../types/MarketData.sol";
|
|
16
|
-
import {PoolState} from "../types/PoolState.sol";
|
|
17
|
-
|
|
18
|
-
import "forge-std/console.sol";
|
|
19
|
-
|
|
20
|
-
// struct PriceOnDemand {
|
|
21
|
-
// address priceFeed;
|
|
22
|
-
// bytes callData;
|
|
23
|
-
// }
|
|
24
|
-
|
|
25
|
-
/// @title Data compressor 3.0.
|
|
26
|
-
/// @notice Collects data from various contracts for use in the dApp
|
|
27
|
-
/// Do not use for data from data compressor for state-changing functions
|
|
28
|
-
contract MarketCompressorV3 {
|
|
29
|
-
// Contract version
|
|
30
|
-
uint256 public constant version = 3_10;
|
|
31
|
-
|
|
32
|
-
PriceFeedCompressor priceOracleCompressor;
|
|
33
|
-
PoolCompressorV3 poolCompressor;
|
|
34
|
-
|
|
35
|
-
error CreditManagerIsNotV3Exception();
|
|
36
|
-
|
|
37
|
-
constructor(address priceOracleCompressorAddress) {
|
|
38
|
-
poolCompressor = new PoolCompressorV3();
|
|
39
|
-
priceOracleCompressor = PriceFeedCompressor(priceOracleCompressorAddress);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function getMarketData(address pool) public view returns (MarketData memory result) {
|
|
43
|
-
result.pool = poolCompressor.getPoolState(pool);
|
|
44
|
-
result.poolQuotaKeeper = poolCompressor.getPoolQuotaKeeperState(result.pool.poolQuotaKeeper);
|
|
45
|
-
result.rateKeeper = poolCompressor.getRateKeeperState(result.poolQuotaKeeper.rateKeeper);
|
|
46
|
-
result.interestRateModel = poolCompressor.getInterestRateModelState(result.pool.interestRateModel);
|
|
47
|
-
|
|
48
|
-
address priceOracle = _getPriceOracle(result.pool);
|
|
49
|
-
address[] memory tokens = IPoolQuotaKeeperV3(result.pool.poolQuotaKeeper).quotedTokens();
|
|
50
|
-
|
|
51
|
-
result.tokens = new address[](tokens.length + 1);
|
|
52
|
-
result.tokens[0] = result.pool.underlying;
|
|
53
|
-
|
|
54
|
-
for (uint256 i = 0; i < tokens.length; i++) {
|
|
55
|
-
result.tokens[i + 1] = tokens[i];
|
|
56
|
-
}
|
|
57
|
-
// How to query if no credit mangers are deployed?
|
|
58
|
-
result.priceOracleData = priceOracleCompressor.getPriceOracleState(priceOracle, result.tokens);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function _getPriceOracle(PoolState memory ps) internal view returns (address) {
|
|
62
|
-
if (ps.creditManagerDebtParams.length == 0) {
|
|
63
|
-
return address(0);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return ICreditManagerV3(ps.creditManagerDebtParams[0].creditManager).priceOracle();
|
|
67
|
-
}
|
|
68
|
-
}
|
|
File without changes
|