Skip to content

Commit 35a4c91

Browse files
fix: zksync tests (#62)
1 parent ecbe493 commit 35a4c91

File tree

6 files changed

+214
-7
lines changed

6 files changed

+214
-7
lines changed

Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,4 @@ git-diff :
3131
deploy-ledger :; FOUNDRY_PROFILE=${chain} forge script $(if $(filter zksync,${chain}),--zksync) ${contract} --rpc-url ${chain} $(if ${dry},--sender 0x25F2226B597E8F9514B3F68F00f494cF4f286491 -vvvv, --ledger --mnemonic-indexes ${MNEMONIC_INDEX} --sender ${LEDGER_SENDER} --verify --verifier etherscan -vvvv --slow --broadcast)
3232
deploy-pk :; FOUNDRY_PROFILE=${chain} forge script $(if $(filter zksync,${chain}),--zksync) ${contract} --rpc-url ${chain} $(if ${dry},--sender 0x25F2226B597E8F9514B3F68F00f494cF4f286491 -vvvv, --private-key ${PRIVATE_KEY} --verify --verifier etherscan -vvvv --slow --broadcast --verifier etherscan)
3333

34-
35-
run-script:; FOUNDRY_PROFILE=${network} forge script $(if $(filter zksync,${network}),--zksync) ${contract} --rpc-url ${network} --sig "run(bool, bool, bool)" ${broadcast} ${generate_diff} ${skip_timelock} -vv
34+
run-script:; FOUNDRY_PROFILE=$(if $(filter zksync,${network}),zksync,test) forge script $(if $(filter zksync,${network}),--zksync) ${contract} --rpc-url ${network} --sig "run(bool, bool, bool)" ${broadcast} ${generate_diff} ${skip_timelock} -vv

foundry.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ src = 'zksync'
1818
test = 'zksync'
1919
script = 'scripts'
2020
libs = ['lib']
21-
solc = '0.8.22'
21+
solc = '0.8.27'
2222
fs_permissions = [{ access = "write", path = "./reports" }]
2323
ffi = true
2424
evm_version = 'shanghai'
@@ -38,6 +38,9 @@ evm_version = 'cancun'
3838
[profile.celo]
3939
evm_version = 'paris'
4040

41+
[profile.test]
42+
evm_version = 'cancun'
43+
4144
[rpc_endpoints]
4245
mainnet = "${RPC_MAINNET}"
4346
optimism = "${RPC_OPTIMISM}"

generator/utils/importsResolver.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,8 @@ function generateRiskStewardImport(code: string) {
4141
const match = code.match(/RiskStewards(\w+)/);
4242

4343
if (match) {
44-
imports = `import {RiskStewards${match[1]}} from '${
45-
match[1] == 'ZkSync' ? '../' : ''
46-
}../../../../scripts/networks/RiskStewards${match[1]}.s.sol';\n`;
44+
imports = `import {RiskStewards${match[1]}} from
45+
'../../../../scripts/networks/RiskStewards${match[1]}.s.sol';\n`;
4746
if (findMatch(code, 'IRiskSteward')) {
4847
imports += `import {IRiskSteward${
4948
findMatch(code, 'IPriceCapAdapter') ? ', IPriceCapAdapter' : ''
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.0;
3+
4+
import {IAaveV3ConfigEngine as IEngine, IPool} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol';
5+
import {IRiskSteward} from '../../src/interfaces/IRiskSteward.sol';
6+
import {IOwnable} from 'aave-address-book/common/IOwnable.sol';
7+
import {IACLManager} from 'aave-address-book/AaveV3.sol';
8+
9+
import {ProtocolV3TestBase} from 'aave-helpers/zksync/src/ProtocolV3TestBase.sol';
10+
11+
abstract contract RiskStewardsBase is ProtocolV3TestBase {
12+
error FailedUpdate();
13+
IPool immutable POOL;
14+
IRiskSteward immutable STEWARD;
15+
16+
uint8 public constant MAX_TX = 6;
17+
18+
constructor(address pool, address steward) {
19+
POOL = IPool(pool);
20+
STEWARD = IRiskSteward(steward);
21+
}
22+
23+
function capsUpdates() public pure virtual returns (IEngine.CapsUpdate[] memory) {}
24+
25+
function collateralsUpdates() public pure virtual returns (IEngine.CollateralUpdate[] memory) {}
26+
27+
function rateStrategiesUpdates()
28+
public
29+
pure
30+
virtual
31+
returns (IEngine.RateStrategyUpdate[] memory)
32+
{}
33+
34+
function eModeCategoriesUpdates()
35+
public
36+
pure
37+
virtual
38+
returns (IEngine.EModeCategoryUpdate[] memory)
39+
{}
40+
41+
function lstPriceCapsUpdates()
42+
public
43+
pure
44+
virtual
45+
returns (IRiskSteward.PriceCapLstUpdate[] memory)
46+
{}
47+
48+
function stablePriceCapsUpdates()
49+
public
50+
pure
51+
virtual
52+
returns (IRiskSteward.PriceCapStableUpdate[] memory)
53+
{}
54+
55+
function name() public pure virtual returns (string memory);
56+
57+
/**
58+
* @notice This script doesn't broadcast as it's intended to be used via safe
59+
*/
60+
function run(bool broadcastToSafe, bool generateDiffReport, bool skipTimelock) external {
61+
vm.startPrank(STEWARD.RISK_COUNCIL());
62+
bytes[] memory callDatas = _simulateAndGenerateDiff(generateDiffReport, skipTimelock);
63+
vm.stopPrank();
64+
65+
if (callDatas.length > 1)
66+
emit log_string('** multiple calldatas emitted, please execute them all **');
67+
emit log_string('safe address');
68+
emit log_address(STEWARD.RISK_COUNCIL());
69+
emit log_string('steward address:');
70+
emit log_address(address(STEWARD));
71+
72+
for (uint8 i = 0; i < callDatas.length; i++) {
73+
emit log_string('calldata:');
74+
emit log_bytes(callDatas[i]);
75+
76+
if (broadcastToSafe) {
77+
_sendToSafe(callDatas[i]);
78+
}
79+
}
80+
}
81+
82+
function _simulateAndGenerateDiff(
83+
bool generateDiffReport,
84+
bool skipTimelock
85+
) internal returns (bytes[] memory) {
86+
bytes[] memory callDatas = new bytes[](MAX_TX);
87+
uint8 txCount;
88+
89+
string memory pre = string(abi.encodePacked('pre_', name()));
90+
string memory post = string(abi.encodePacked('post_', name()));
91+
92+
IEngine.CapsUpdate[] memory capUpdates = capsUpdates();
93+
IEngine.CollateralUpdate[] memory collateralUpdates = collateralsUpdates();
94+
IEngine.EModeCategoryUpdate[] memory eModeUpdates = eModeCategoriesUpdates();
95+
IEngine.RateStrategyUpdate[] memory rateUpdates = rateStrategiesUpdates();
96+
IRiskSteward.PriceCapLstUpdate[] memory lstPriceCapUpdates = lstPriceCapsUpdates();
97+
IRiskSteward.PriceCapStableUpdate[] memory stablePriceCapUpdates = stablePriceCapsUpdates();
98+
99+
if (skipTimelock) {
100+
vm.warp(block.timestamp + 15 days);
101+
}
102+
103+
if (generateDiffReport) createConfigurationSnapshot(pre, POOL, true, true, false, false);
104+
105+
if (capUpdates.length != 0) {
106+
callDatas[txCount] = abi.encodeWithSelector(IRiskSteward.updateCaps.selector, capUpdates);
107+
(bool success, bytes memory resultData) = address(STEWARD).call(callDatas[txCount]);
108+
_verifyCallResult(success, resultData);
109+
110+
txCount++;
111+
}
112+
113+
if (collateralUpdates.length != 0) {
114+
callDatas[txCount] = abi.encodeWithSelector(
115+
IRiskSteward.updateCollateralSide.selector,
116+
collateralUpdates
117+
);
118+
(bool success, bytes memory resultData) = address(STEWARD).call(callDatas[txCount]);
119+
_verifyCallResult(success, resultData);
120+
txCount++;
121+
}
122+
123+
if (eModeUpdates.length != 0) {
124+
callDatas[txCount] = abi.encodeWithSelector(
125+
IRiskSteward.updateEModeCategories.selector,
126+
eModeUpdates
127+
);
128+
(bool success, bytes memory resultData) = address(STEWARD).call(callDatas[txCount]);
129+
_verifyCallResult(success, resultData);
130+
txCount++;
131+
}
132+
133+
if (rateUpdates.length != 0) {
134+
callDatas[txCount] = abi.encodeWithSelector(IRiskSteward.updateRates.selector, rateUpdates);
135+
(bool success, bytes memory resultData) = address(STEWARD).call(callDatas[txCount]);
136+
_verifyCallResult(success, resultData);
137+
txCount++;
138+
}
139+
140+
if (lstPriceCapUpdates.length != 0) {
141+
callDatas[txCount] = abi.encodeWithSelector(
142+
IRiskSteward.updateLstPriceCaps.selector,
143+
lstPriceCapUpdates
144+
);
145+
(bool success, bytes memory resultData) = address(STEWARD).call(callDatas[txCount]);
146+
_verifyCallResult(success, resultData);
147+
txCount++;
148+
}
149+
150+
if (stablePriceCapUpdates.length != 0) {
151+
callDatas[txCount] = abi.encodeWithSelector(
152+
IRiskSteward.updateStablePriceCaps.selector,
153+
stablePriceCapUpdates
154+
);
155+
(bool success, bytes memory resultData) = address(STEWARD).call(callDatas[txCount]);
156+
_verifyCallResult(success, resultData);
157+
txCount++;
158+
}
159+
160+
if (generateDiffReport) {
161+
createConfigurationSnapshot(post, POOL, true, true, false, false);
162+
diffReports(pre, post);
163+
}
164+
165+
// we defined the callDatas with MAX_TX size, we now squash it to the number of txs
166+
assembly {
167+
mstore(callDatas, txCount)
168+
}
169+
return callDatas;
170+
}
171+
172+
function _sendToSafe(bytes memory callDatas) internal {
173+
string[] memory inputs = new string[](8);
174+
inputs[0] = 'npx';
175+
inputs[1] = 'ts-node';
176+
inputs[2] = 'scripts/safe-helper.ts';
177+
inputs[3] = vm.toString(STEWARD.RISK_COUNCIL());
178+
inputs[4] = vm.toString(address(STEWARD));
179+
inputs[5] = vm.toString(callDatas);
180+
inputs[6] = vm.toString(block.chainid);
181+
inputs[7] = 'Call';
182+
vm.ffi(inputs);
183+
}
184+
185+
function _verifyCallResult(
186+
bool success,
187+
bytes memory returnData
188+
) private pure returns (bytes memory) {
189+
if (success) {
190+
return returnData;
191+
} else {
192+
// Look for revert reason and bubble it up if present
193+
if (returnData.length > 0) {
194+
// The easiest way to bubble the revert reason is using memory via assembly
195+
196+
// solhint-disable-next-line no-inline-assembly
197+
assembly {
198+
let returndata_size := mload(returnData)
199+
revert(add(32, returnData), returndata_size)
200+
}
201+
} else {
202+
revert FailedUpdate();
203+
}
204+
}
205+
}
206+
}

zksync/src/contracts/examples/ZkSyncExample.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pragma solidity ^0.8.0;
44
import {AaveV3ZkSyncAssets} from 'aave-address-book/AaveV3ZkSync.sol';
55
import {IAaveV3ConfigEngine as IEngine} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol';
66
import {EngineFlags} from 'aave-v3-origin/src/contracts/extensions/v3-config-engine/EngineFlags.sol';
7-
import {RiskStewardsZkSync} from '../../../../scripts/networks/RiskStewardsZkSync.s.sol';
7+
import {RiskStewardsZkSync} from '../../../scripts/networks/RiskStewardsZkSync.s.sol';
88

99
// make run-script network=zksync contract=zksync/src/contracts/examples/ZkSyncExample.sol broadcast=false generate_diff=true skip_timelock=false
1010
contract ZkSyncExample is RiskStewardsZkSync {

0 commit comments

Comments
 (0)