Skip to content

Commit 774ea78

Browse files
committed
test: registry checks; address lib horizon
1 parent 2d7d378 commit 774ea78

File tree

2 files changed

+292
-0
lines changed

2 files changed

+292
-0
lines changed
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.0;
3+
4+
import {Test, Vm} from 'forge-std/Test.sol';
5+
import {AaveV3HorizonEthereum} from './utils/AaveV3HorizonEthereum.sol';
6+
7+
/// forge-config: default.evm_version = "cancun"
8+
contract OracleDynamicBoundsTest is Test {
9+
function setUp() public {
10+
vm.createSelectFork('mainnet', 23469081);
11+
}
12+
struct ExpectedParams {
13+
uint64 maxExpectedApy;
14+
uint32 upperBoundTolerance;
15+
uint32 lowerBoundTolerance;
16+
uint32 maxDiscount;
17+
uint80 lookbackWindowSize;
18+
bool isUpperBoundEnabled;
19+
bool isLowerBoundEnabled;
20+
bool isActionTakingEnabled;
21+
}
22+
23+
ExpectedParams internal USTB_EXPECTED_PARAMS =
24+
ExpectedParams({
25+
maxExpectedApy: 415,
26+
upperBoundTolerance: 15,
27+
lowerBoundTolerance: 5,
28+
maxDiscount: 10,
29+
lookbackWindowSize: 4,
30+
isUpperBoundEnabled: true,
31+
isLowerBoundEnabled: true,
32+
isActionTakingEnabled: false
33+
});
34+
ExpectedParams internal USCC_EXPECTED_PARAMS =
35+
ExpectedParams({
36+
maxExpectedApy: 2500,
37+
upperBoundTolerance: 50,
38+
lowerBoundTolerance: 10,
39+
maxDiscount: 40,
40+
lookbackWindowSize: 4,
41+
isUpperBoundEnabled: true,
42+
isLowerBoundEnabled: true,
43+
isActionTakingEnabled: false
44+
});
45+
ExpectedParams internal USYC_EXPECTED_PARAMS =
46+
ExpectedParams({
47+
maxExpectedApy: 420,
48+
upperBoundTolerance: 15,
49+
lowerBoundTolerance: 5,
50+
maxDiscount: 10,
51+
lookbackWindowSize: 4,
52+
isUpperBoundEnabled: true,
53+
isLowerBoundEnabled: true,
54+
isActionTakingEnabled: false
55+
});
56+
ExpectedParams internal JTRSY_EXPECTED_PARAMS =
57+
ExpectedParams({
58+
maxExpectedApy: 390,
59+
upperBoundTolerance: 15,
60+
lowerBoundTolerance: 5,
61+
maxDiscount: 10,
62+
lookbackWindowSize: 4,
63+
isUpperBoundEnabled: true,
64+
isLowerBoundEnabled: true,
65+
isActionTakingEnabled: false
66+
});
67+
ExpectedParams internal JAAA_EXPECTED_PARAMS =
68+
ExpectedParams({
69+
maxExpectedApy: 520,
70+
upperBoundTolerance: 50,
71+
lowerBoundTolerance: 10,
72+
maxDiscount: 75,
73+
lookbackWindowSize: 4,
74+
isUpperBoundEnabled: true,
75+
isLowerBoundEnabled: true,
76+
isActionTakingEnabled: false
77+
});
78+
ExpectedParams internal VBILL_EXPECTED_PARAMS =
79+
ExpectedParams({
80+
maxExpectedApy: 0,
81+
upperBoundTolerance: 10,
82+
lowerBoundTolerance: 10,
83+
maxDiscount: 0,
84+
lookbackWindowSize: 4,
85+
isUpperBoundEnabled: true,
86+
isLowerBoundEnabled: true,
87+
isActionTakingEnabled: false
88+
});
89+
90+
function test_registry_admin() external {
91+
(bool success, bytes memory data) = AaveV3HorizonEthereum.PARAM_REGISTRY.call(
92+
abi.encodeWithSignature('owner()')
93+
);
94+
require(success, 'Failed to call owner()');
95+
address owner = abi.decode(data, (address));
96+
assertEq(owner, AaveV3HorizonEthereum.HORIZON_OPS, 'owner');
97+
98+
(success, data) = AaveV3HorizonEthereum.PARAM_REGISTRY.call(
99+
abi.encodeWithSignature('updater()')
100+
);
101+
require(success, 'Failed to call owner()');
102+
address updater = abi.decode(data, (address));
103+
assertEq(updater, AaveV3HorizonEthereum.HORIZON_OPS, 'updater');
104+
}
105+
106+
function test_ustb_oracle() external {
107+
test_horizon_adapter(
108+
AaveV3HorizonEthereum.USTB_ADDRESS,
109+
AaveV3HorizonEthereum.USTB_PRICE_FEED_ADAPTER,
110+
true
111+
);
112+
test_registry_params(AaveV3HorizonEthereum.USTB_ADDRESS, USTB_EXPECTED_PARAMS);
113+
test_lookback_data(AaveV3HorizonEthereum.USTB_ADDRESS);
114+
}
115+
116+
function test_uscc_oracle() external {
117+
test_horizon_adapter(
118+
AaveV3HorizonEthereum.USCC_ADDRESS,
119+
AaveV3HorizonEthereum.USCC_PRICE_FEED_ADAPTER,
120+
true
121+
);
122+
test_registry_params(AaveV3HorizonEthereum.USCC_ADDRESS, USCC_EXPECTED_PARAMS);
123+
test_lookback_data(AaveV3HorizonEthereum.USCC_ADDRESS);
124+
}
125+
126+
function test_usyc_oracle() external {
127+
test_horizon_adapter(
128+
AaveV3HorizonEthereum.USYC_ADDRESS,
129+
AaveV3HorizonEthereum.USYC_PRICE_FEED,
130+
false
131+
);
132+
test_registry_params(AaveV3HorizonEthereum.USYC_ADDRESS, USYC_EXPECTED_PARAMS);
133+
test_lookback_data(AaveV3HorizonEthereum.USYC_ADDRESS);
134+
}
135+
136+
function test_jtrsy_oracle() external {
137+
test_horizon_adapter(
138+
AaveV3HorizonEthereum.JTRSY_ADDRESS,
139+
AaveV3HorizonEthereum.JTRSY_PRICE_FEED_ADAPTER,
140+
true
141+
);
142+
test_registry_params(AaveV3HorizonEthereum.JTRSY_ADDRESS, JTRSY_EXPECTED_PARAMS);
143+
test_lookback_data(AaveV3HorizonEthereum.JTRSY_ADDRESS);
144+
}
145+
146+
function test_jaaa_oracle() external {
147+
test_horizon_adapter(
148+
AaveV3HorizonEthereum.JAAA_ADDRESS,
149+
AaveV3HorizonEthereum.JAAA_PRICE_FEED_ADAPTER,
150+
true
151+
);
152+
test_registry_params(AaveV3HorizonEthereum.JAAA_ADDRESS, JAAA_EXPECTED_PARAMS);
153+
test_lookback_data(AaveV3HorizonEthereum.JAAA_ADDRESS);
154+
}
155+
156+
function test_vbill() external {
157+
test_horizon_adapter(
158+
AaveV3HorizonEthereum.VBILL_ADDRESS,
159+
AaveV3HorizonEthereum.VBILL_PRICE_FEED,
160+
false
161+
);
162+
test_registry_params(AaveV3HorizonEthereum.VBILL_ADDRESS, VBILL_EXPECTED_PARAMS);
163+
test_lookback_data(AaveV3HorizonEthereum.VBILL_ADDRESS);
164+
}
165+
166+
function test_registry_params(address asset, ExpectedParams memory expectedParams) internal {
167+
bool success;
168+
bytes memory data;
169+
170+
(success, data) = AaveV3HorizonEthereum.PARAM_REGISTRY.call(
171+
abi.encodeWithSignature('assetExists(address)', asset)
172+
);
173+
require(success, 'Failed to call assetExists()');
174+
bool exists = abi.decode(data, (bool));
175+
assertEq(exists, true, 'assetExists');
176+
177+
(success, data) = AaveV3HorizonEthereum.PARAM_REGISTRY.call(
178+
abi.encodeWithSignature('getParametersForAsset(address)', asset)
179+
);
180+
require(success, 'Failed to call getParametersForAsset()');
181+
182+
(
183+
uint64 maxExpectedApy,
184+
uint32 upperBoundTolerance,
185+
uint32 lowerBoundTolerance,
186+
uint32 maxDiscount,
187+
uint80 lookbackWindowSize,
188+
bool isUpperBoundEnabled,
189+
bool isLowerBoundEnabled,
190+
bool isActionTakingEnabled
191+
) = abi.decode(data, (uint64, uint32, uint32, uint32, uint80, bool, bool, bool));
192+
193+
assertEq(maxExpectedApy, expectedParams.maxExpectedApy, 'maxExpectedApy');
194+
assertEq(upperBoundTolerance, expectedParams.upperBoundTolerance, 'upperBoundTolerance');
195+
assertEq(lowerBoundTolerance, expectedParams.lowerBoundTolerance, 'lowerBoundTolerance');
196+
assertEq(maxDiscount, expectedParams.maxDiscount, 'maxDiscount');
197+
assertEq(lookbackWindowSize, expectedParams.lookbackWindowSize, 'lookbackWindowSize');
198+
assertEq(isUpperBoundEnabled, expectedParams.isUpperBoundEnabled, 'isUpperBoundEnabled');
199+
assertEq(isLowerBoundEnabled, expectedParams.isLowerBoundEnabled, 'isLowerBoundEnabled');
200+
assertEq(isActionTakingEnabled, expectedParams.isActionTakingEnabled, 'isActionTakingEnabled');
201+
}
202+
203+
function test_horizon_adapter(address asset, address source, bool isAdapter) internal {
204+
bool success;
205+
bytes memory data;
206+
if (isAdapter) {
207+
// oracle source from horizon adapter
208+
(success, data) = source.call(abi.encodeWithSignature('source()'));
209+
require(success, 'Failed to call source()');
210+
source = abi.decode(data, (address));
211+
}
212+
213+
// oracle address from param registry
214+
(success, data) = AaveV3HorizonEthereum.PARAM_REGISTRY.call(
215+
abi.encodeWithSignature('getOracle(address)', asset)
216+
);
217+
require(success, 'Failed to call getOracle()');
218+
address oracle = abi.decode(data, (address));
219+
220+
assertEq(source, oracle, 'source');
221+
}
222+
223+
function test_lookback_data(address asset) internal {
224+
bool success;
225+
bytes memory data;
226+
227+
(success, data) = AaveV3HorizonEthereum.PARAM_REGISTRY.call(
228+
abi.encodeWithSignature('getLookbackData(address)', asset)
229+
);
230+
require(success, 'Failed to call getLookbackData()');
231+
232+
(
233+
uint80 roundId,
234+
int256 answer,
235+
uint256 startedAt,
236+
uint256 updatedAt,
237+
uint80 answeredInRound
238+
) = abi.decode(data, (uint80, int256, uint256, uint256, uint80));
239+
240+
assertGt(roundId, 0, 'roundId');
241+
assertGt(answer, 0, 'answer');
242+
assertApproxEqRel(startedAt, vm.getBlockTimestamp() - 4 * 1 days, 1e14, 'startedAt');
243+
assertApproxEqRel(updatedAt, vm.getBlockTimestamp() - 4 * 1 days, 1e14, 'updatedAt');
244+
assertGt(answeredInRound, 0, 'answeredInRound');
245+
}
246+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
library AaveV3HorizonEthereum {
4+
address public constant HORIZON_OPS = 0xE6ec1f0Ae6Cd023bd0a9B4d0253BDC755103253c;
5+
address public constant HORIZON_EMERGENCY = 0x13B57382c36BAB566E75C72303622AF29E27e1d3;
6+
7+
// horizon deployments
8+
// address internal constant CONFIG_ENGINE = 0x366D1e3F41Ad5CC699bb8FC0B41323C68d895E2c;
9+
address internal constant POOL_ADDRESSES_PROVIDER = 0x5D39E06b825C1F2B80bf2756a73e28eFAA128ba0;
10+
address internal constant POOL = 0xAe05Cd22df81871bc7cC2a04BeCfb516bFe332C8;
11+
address internal constant POOL_CONFIGURATOR = 0x83Cb1B4af26EEf6463aC20AFbAC9c0e2E017202F;
12+
address internal constant ACL_MANAGER = 0xEFD5df7b87d2dCe6DD454b4240b3e0A4db562321;
13+
address internal constant AAVE_PROTOCOL_DATA_PROVIDER =
14+
0x53519c32f73fE1797d10210c4950fFeBa3b21504;
15+
address internal constant ATOKEN_IMPLEMENTATION = 0xB2668573828029917ffbD1e76270373511818498;
16+
address internal constant RWA_ATOKEN_IMPLEMENTATION = 0x8CA2a49c7Df42E67F9A532F0d383D648fB7Fe4C9;
17+
address internal constant VARIABLE_DEBT_TOKEN_IMPLEMENTATION =
18+
0x15F03E5dE87c12cb2e2b8e5d6ECEf0a9E21ab269;
19+
address internal constant DEFAULT_INTEREST_RATE_STRATEGY =
20+
0x87593272C06f4FC49EC2942eBda0972d2F1Ab521;
21+
address internal constant REVENUE_SPLITTER = 0x70CC725B8f05e0f230B05C4e91ABc651E121354f;
22+
address internal constant REWARDS_CONTROLLER = 0x1D5D386a90CEA8AcEa9fa75389e97CF5F1AE21D3;
23+
address internal constant AAVE_ORACLE = 0x985BcfAB7e0f4EF2606CC5b64FC1A16311880442;
24+
25+
// horizon assets
26+
address public constant USTB_ADDRESS = 0x43415eB6ff9DB7E26A15b704e7A3eDCe97d31C4e;
27+
address public constant USTB_PRICE_FEED_ADAPTER = 0x5Ae4D93B9b9626Dc3289e1Afb14b821FD3C95F44;
28+
29+
address public constant USCC_ADDRESS = 0x14d60E7FDC0D71d8611742720E4C50E7a974020c;
30+
address public constant USCC_PRICE_FEED_ADAPTER = 0x14CB2E810Eb93b79363f489D45a972b609E47230;
31+
32+
address public constant USYC_ADDRESS = 0x136471a34f6ef19fE571EFFC1CA711fdb8E49f2b;
33+
address public constant USYC_PRICE_FEED = 0xE8E65Fb9116875012F5990Ecaab290B3531DbeB9;
34+
35+
address public constant JTRSY_ADDRESS = 0x8c213ee79581Ff4984583C6a801e5263418C4b86;
36+
address public constant JTRSY_PRICE_FEED_ADAPTER = 0xfAB6790E399f0481e1303167c655b3c39ee6e7A0;
37+
38+
address public constant JAAA_ADDRESS = 0x5a0F93D040De44e78F251b03c43be9CF317Dcf64;
39+
address public constant JAAA_PRICE_FEED_ADAPTER = 0xF77f2537dba4ffD60f77fACdfB2c1706364fA03d;
40+
41+
address public constant VBILL_ADDRESS = 0x2255718832bC9fD3bE1CaF75084F4803DA14FF01;
42+
address public constant VBILL_PRICE_FEED = 0x5ed77a9D9b7cc80E9d0D7711024AF38C2643C1c4;
43+
44+
// oracle param registry
45+
address public constant PARAM_REGISTRY = 0x69D55D504BC9556E377b340D19818E736bbB318b;
46+
}

0 commit comments

Comments
 (0)