Skip to content

Commit e5d2b24

Browse files
committed
test: expand tests to every coll/debt combo
1 parent 5e443e8 commit e5d2b24

2 files changed

Lines changed: 73 additions & 46 deletions

File tree

tests/utils/HorizonRwaWhitelistHelper.sol

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,21 +212,40 @@ abstract contract HorizonRwaWhitelistHelper is Test {
212212
(success, ) = registryService.call(
213213
abi.encodeWithSignature('addWallet(address,string)', addressToWhitelist, fundId)
214214
);
215-
if (success) {
216-
require(
217-
_isSecuritizeWhitelisted(registryService, addressToWhitelist),
218-
'Securitize: address not whitelisted'
219-
);
220-
}
215+
// always verify the address is whitelisted as a regular wallet OR passes compliance as a special wallet.
216+
require(
217+
_isSecuritizeWhitelisted(registryService, addressToWhitelist) ||
218+
_passesSecuritizeCompliance(token, addressToWhitelist),
219+
'Securitize: not whitelisted'
220+
);
221221
}
222222

223+
/// @dev Returns true if `addr` is whitelisted as a regular wallet.
223224
function _isSecuritizeWhitelisted(address registryService, address addr) internal returns (bool) {
224225
(bool success, bytes memory data) = registryService.call(
225226
abi.encodeWithSignature('isWallet(address)', addr)
226227
);
227228
return success && abi.decode(data, (bool));
228229
}
229230

231+
/// @dev Checks if `addr` passes the DS compliance service's preTransferCheck (code 0 = allowed).
232+
function _passesSecuritizeCompliance(address token, address addr) internal returns (bool) {
233+
(bool success, bytes memory data) = token.call(abi.encodeWithSignature('COMPLIANCE_SERVICE()'));
234+
if (!success) return false;
235+
(success, data) = token.call(
236+
abi.encodeWithSignature('getDSService(uint256)', abi.decode(data, (uint256)))
237+
);
238+
if (!success) return false;
239+
address complianceService = abi.decode(data, (address));
240+
241+
(success, data) = complianceService.call(
242+
abi.encodeWithSignature('preTransferCheck(address,address,uint256)', addr, addr, 0)
243+
);
244+
if (!success) return false;
245+
(uint256 code, ) = abi.decode(data, (uint256, string));
246+
return code == 0;
247+
}
248+
230249
/// @dev Returns true if `token` requires tokens from whale instead of foundry's `deal`.
231250
function _needsWhaleDeal(address token) internal pure returns (bool) {
232251
return

tests/utils/ProtocolV3HorizonTestBase.sol

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,18 @@ abstract contract ProtocolV3HorizonTestBase is
106106
*/
107107
function e2eTest_v3_3(IPool pool) public {
108108
ReserveConfig[] memory configs = _getReservesConfigs(pool);
109-
ReserveConfig memory collateralConfig = _goodRandomCollateral(configs);
110109
uint256 snapshot = vm.snapshotState();
111-
for (uint256 i; i < configs.length; i++) {
112-
if (_includeInE2e(configs[i])) {
113-
e2eTestAsset_v3_3(pool, collateralConfig, configs[i]);
114-
vm.revertToState(snapshot);
115-
} else {
116-
console.log('E2E: TestAsset %s SKIPPED', configs[i].symbol);
110+
for (uint256 c; c < configs.length; c++) {
111+
if (!_isGoodCollateral(configs[c])) {
112+
continue;
113+
}
114+
for (uint256 i; i < configs.length; i++) {
115+
if (_includeInE2e(configs[i])) {
116+
e2eTestAsset_v3_3(pool, configs[c], configs[i]);
117+
vm.revertToState(snapshot);
118+
} else {
119+
console.log('E2E: TestAsset %s SKIPPED', configs[i].symbol);
120+
}
117121
}
118122
}
119123
}
@@ -150,14 +154,9 @@ abstract contract ProtocolV3HorizonTestBase is
150154

151155
// eMode supplier enters eMode; regular supplier stays in eMode 0
152156
_enableIfEMode(collateralConfig, pool, emodeCollateralSupplier);
153-
_deposit(collateralConfig, pool, emodeCollateralSupplier, vars.collateralAssetAmount);
154-
_deposit(collateralConfig, pool, regularCollateralSupplier, vars.collateralAssetAmount);
155-
// transfer from whale for tokens when `deal` doesn't work
156-
// needed for assets like ACRED / VBILL that use DSToken, issues due to internal token accounting
157-
if (_needsWhaleDeal(testAssetConfig.underlying)) {
158-
_dealRwaToken(testAssetConfig.underlying, testAssetSupplier, vars.testAssetAmount);
159-
}
160-
_deposit(testAssetConfig, pool, testAssetSupplier, vars.testAssetAmount);
157+
_supply(collateralConfig, pool, emodeCollateralSupplier, vars.collateralAssetAmount);
158+
_supply(collateralConfig, pool, regularCollateralSupplier, vars.collateralAssetAmount);
159+
_supply(testAssetConfig, pool, testAssetSupplier, vars.testAssetAmount);
161160

162161
uint256 snapshotAfterDeposits = vm.snapshotState();
163162

@@ -192,14 +191,14 @@ abstract contract ProtocolV3HorizonTestBase is
192191
vm.prank(addressesProvider.getACLAdmin());
193192
poolConfigurator.setSupplyCap(testAssetConfig.underlying, 0);
194193

195-
_deposit(
194+
_supply(
196195
testAssetConfig,
197196
pool,
198197
testAssetSupplier,
199198
vars.borrowAmount - vars.aTokenTotalSupply
200199
);
201200

202-
_deposit(
201+
_supply(
203202
collateralConfig,
204203
pool,
205204
regularCollateralSupplier,
@@ -427,29 +426,6 @@ abstract contract ProtocolV3HorizonTestBase is
427426
}
428427
}
429428

430-
/**
431-
* @dev returns a random "good" collateral from the list
432-
*/
433-
function _goodRandomCollateral(
434-
ReserveConfig[] memory configs
435-
) internal returns (ReserveConfig memory config) {
436-
bool found;
437-
for (uint256 i; i < configs.length; i++) {
438-
if (_isGoodCollateral(configs[i])) {
439-
found = true;
440-
break;
441-
}
442-
}
443-
require(found, 'ERROR: No usable collateral found');
444-
445-
while (true) {
446-
uint256 idx = vm.randomUint(0, configs.length - 1);
447-
if (_isGoodCollateral(configs[idx])) {
448-
return configs[idx];
449-
}
450-
}
451-
}
452-
453429
function _isGoodCollateral(ReserveConfig memory config) internal pure returns (bool) {
454430
return
455431
_includeInE2e(config) &&
@@ -458,6 +434,38 @@ abstract contract ProtocolV3HorizonTestBase is
458434
config.ltv != 0;
459435
}
460436

437+
/**
438+
* @dev Overrides `_deposit` to use whale transfers for tokens incompatible with
439+
* foundry's `deal` (e.g. Securitize DSTokens that store balances in an external data store).
440+
*/
441+
function _supply(
442+
ReserveConfig memory config,
443+
IPool pool,
444+
address user,
445+
uint256 amount
446+
) internal virtual {
447+
if (_needsWhaleDeal(config.underlying)) {
448+
require(!config.isFrozen, 'DEPOSIT(): FROZEN_RESERVE');
449+
require(config.isActive, 'DEPOSIT(): INACTIVE_RESERVE');
450+
require(!config.isPaused, 'DEPOSIT(): PAUSED_RESERVE');
451+
452+
uint256 aTokenBefore = IERC20(config.aToken).balanceOf(user);
453+
454+
_dealRwaToken(config.underlying, user, amount);
455+
456+
vm.startPrank(user);
457+
IERC20(config.underlying).approve(address(pool), amount);
458+
console.log('SUPPLY: %s, Amount: %s', config.symbol, amount);
459+
pool.supply(config.underlying, amount, user, 0);
460+
vm.stopPrank();
461+
462+
uint256 aTokenAfter = IERC20(config.aToken).balanceOf(user);
463+
assertApproxEqAbs(aTokenAfter, aTokenBefore + amount, 2);
464+
} else {
465+
_deposit(config, pool, user, amount);
466+
}
467+
}
468+
461469
/**
462470
* @dev Checks if testAsset is borrowable in any eMode where collateral is accepted.
463471
*/

0 commit comments

Comments
 (0)