@bgd-labs/toolbox 0.0.2 → 0.0.4

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/dist/index.js CHANGED
@@ -30,14 +30,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ EVENT_DB: () => EVENT_DB,
33
34
  HALF_RAY: () => HALF_RAY,
34
35
  HALF_WAD: () => HALF_WAD,
35
36
  HUMAN_READABLE_PAYLOAD_STATE: () => HUMAN_READABLE_PAYLOAD_STATE,
36
37
  HUMAN_READABLE_PROPOSAL_STATE: () => HUMAN_READABLE_PROPOSAL_STATE,
37
38
  LTV_PRECISION: () => LTV_PRECISION,
38
39
  PayloadState: () => PayloadState,
40
+ ProposalState: () => ProposalState,
39
41
  RAY: () => RAY,
40
42
  SECONDS_PER_YEAR: () => SECONDS_PER_YEAR,
43
+ SelfdestuctCheckState: () => SelfdestuctCheckState,
41
44
  WAD: () => WAD,
42
45
  WAD_RAY_RATIO: () => WAD_RAY_RATIO,
43
46
  bitmapToIndexes: () => bitmapToIndexes,
@@ -45,12 +48,16 @@ __export(index_exports, {
45
48
  calculateCompoundedInterest: () => calculateCompoundedInterest,
46
49
  calculateHealthFactorFromBalances: () => calculateHealthFactorFromBalances,
47
50
  calculateLinearInterest: () => calculateLinearInterest,
51
+ checkForSelfdestruct: () => checkForSelfdestruct,
48
52
  decodeReserveConfiguration: () => decodeReserveConfiguration,
49
53
  decodeReserveConfigurationV2: () => decodeReserveConfigurationV2,
50
54
  decodeUserConfiguration: () => decodeUserConfiguration,
51
55
  diffCode: () => diffCode,
56
+ diffFoundryStorageLayout: () => diffFoundryStorageLayout,
52
57
  erc1967_AdminSlot: () => erc1967_AdminSlot,
53
58
  erc1967_ImplementationSlot: () => erc1967_ImplementationSlot,
59
+ foundry_getStandardJsonInput: () => foundry_getStandardJsonInput,
60
+ foundry_getStorageLayout: () => foundry_getStorageLayout,
54
61
  getBits: () => getBits,
55
62
  getCurrentDebtBalance: () => getCurrentDebtBalance,
56
63
  getCurrentLiquidityBalance: () => getCurrentLiquidityBalance,
@@ -58,18 +65,26 @@ __export(index_exports, {
58
65
  getGovernance: () => getGovernance,
59
66
  getMarketReferenceCurrencyAndUsdBalance: () => getMarketReferenceCurrencyAndUsdBalance,
60
67
  getNonFinalizedPayloads: () => getNonFinalizedPayloads,
68
+ getNonFinalizedProposals: () => getNonFinalizedProposals,
61
69
  getNormalizedDebt: () => getNormalizedDebt,
62
70
  getNormalizedIncome: () => getNormalizedIncome,
63
71
  getPayloadsController: () => getPayloadsController,
64
72
  getSourceCode: () => getSourceCode,
73
+ isPayloadFinal: () => isPayloadFinal,
74
+ isProposalFinal: () => isProposalFinal,
65
75
  makePayloadExecutableOnTestClient: () => makePayloadExecutableOnTestClient,
66
76
  makeProposalExecutableOnTestClient: () => makeProposalExecutableOnTestClient,
67
- parseApiSourceCode: () => parseApiSourceCode,
77
+ parseEtherscanStyleSourceCode: () => parseEtherscanStyleSourceCode,
78
+ parseLogs: () => parseLogs,
68
79
  rayDiv: () => rayDiv,
69
80
  rayMul: () => rayMul,
70
81
  rayToWad: () => rayToWad,
82
+ renderTenderlyReport: () => renderTenderlyReport,
71
83
  setBits: () => setBits,
72
84
  tenderly_createVnet: () => tenderly_createVnet,
85
+ tenderly_deleteVnet: () => tenderly_deleteVnet,
86
+ tenderly_getVnet: () => tenderly_getVnet,
87
+ tenderly_simVnet: () => tenderly_simVnet,
73
88
  wadDiv: () => wadDiv,
74
89
  wadToRay: () => wadToRay
75
90
  });
@@ -1954,15 +1969,17 @@ async function makePayloadExecutableOnTestClient(client, payloadsController, pay
1954
1969
  )
1955
1970
  });
1956
1971
  }
1972
+ function isPayloadFinal(state) {
1973
+ return ![2 /* Queued */, 1 /* Created */].includes(state);
1974
+ }
1957
1975
  async function getNonFinalizedPayloads(client, payloadsController) {
1958
1976
  const controllerContract = getPayloadsController(client, payloadsController);
1959
1977
  const payloadsCount = await controllerContract.read.getPayloadsCount();
1960
1978
  const nonFinalPayloads = [];
1961
- for (const payloadId of [...Array(Number(payloadsCount)).keys()].reverse()) {
1979
+ for (let payloadId = payloadsCount - 1; payloadId != 0; payloadId--) {
1962
1980
  const maxRange = (35 + 10 + 7) * 24 * 60 * 60;
1963
1981
  const payload = await controllerContract.read.getPayloadById([payloadId]);
1964
- if ([2 /* Queued */, 1 /* Created */].includes(payload.state))
1965
- nonFinalPayloads.push(payloadId);
1982
+ if (!isPayloadFinal(payload.state)) nonFinalPayloads.push(payloadId);
1966
1983
  if (payload.createdAt < Date.now() / 1e3 - maxRange) break;
1967
1984
  }
1968
1985
  return nonFinalPayloads;
@@ -1971,15 +1988,26 @@ async function getNonFinalizedPayloads(client, payloadsController) {
1971
1988
  // src/aave/governance/governance.ts
1972
1989
  var import_viem3 = require("viem");
1973
1990
  var import_actions2 = require("viem/actions");
1991
+ var ProposalState = /* @__PURE__ */ ((ProposalState2) => {
1992
+ ProposalState2[ProposalState2["Null"] = 0] = "Null";
1993
+ ProposalState2[ProposalState2["Created"] = 1] = "Created";
1994
+ ProposalState2[ProposalState2["Active"] = 2] = "Active";
1995
+ ProposalState2[ProposalState2["Queued"] = 3] = "Queued";
1996
+ ProposalState2[ProposalState2["Executed"] = 4] = "Executed";
1997
+ ProposalState2[ProposalState2["Failed"] = 5] = "Failed";
1998
+ ProposalState2[ProposalState2["Cancelled"] = 6] = "Cancelled";
1999
+ ProposalState2[ProposalState2["Expired"] = 7] = "Expired";
2000
+ return ProposalState2;
2001
+ })(ProposalState || {});
1974
2002
  var HUMAN_READABLE_PROPOSAL_STATE = {
1975
- [ProposalState.Null]: "Null",
1976
- [ProposalState.Created]: "Created",
1977
- [ProposalState.Active]: "Active",
1978
- [ProposalState.Queued]: "Queued",
1979
- [ProposalState.Executed]: "Executed",
1980
- [ProposalState.Failed]: "Failed",
1981
- [ProposalState.Cancelled]: "Cancelled",
1982
- [ProposalState.Expired]: "Expired"
2003
+ [0 /* Null */]: "Null",
2004
+ [1 /* Created */]: "Created",
2005
+ [2 /* Active */]: "Active",
2006
+ [3 /* Queued */]: "Queued",
2007
+ [4 /* Executed */]: "Executed",
2008
+ [5 /* Failed */]: "Failed",
2009
+ [6 /* Cancelled */]: "Cancelled",
2010
+ [7 /* Expired */]: "Expired"
1983
2011
  };
1984
2012
  function getGovernance(client, address) {
1985
2013
  return (0, import_viem3.getContract)({
@@ -2000,7 +2028,7 @@ async function makeProposalExecutableOnTestClient(client, governance, proposalId
2000
2028
  manipulatedStorage,
2001
2029
  0n,
2002
2030
  8n,
2003
- ProposalState.Queued
2031
+ 3 /* Queued */
2004
2032
  );
2005
2033
  manipulatedStorage = setBits(
2006
2034
  manipulatedStorage,
@@ -2016,6 +2044,24 @@ async function makeProposalExecutableOnTestClient(client, governance, proposalId
2016
2044
  value: (0, import_viem3.toHex)(manipulatedStorage, { size: 32 })
2017
2045
  });
2018
2046
  }
2047
+ function isProposalFinal(state) {
2048
+ return ![
2049
+ 3 /* Queued */,
2050
+ 1 /* Created */,
2051
+ 2 /* Active */
2052
+ ].includes(state);
2053
+ }
2054
+ async function getNonFinalizedProposals(client, governanceAddress) {
2055
+ const goverannceContract = getGovernance(client, governanceAddress);
2056
+ const proposalsCount = await goverannceContract.read.getProposalsCount();
2057
+ const nonFinalProposals = [];
2058
+ for (let proposalId = proposalsCount - 1n; proposalId != 0n; proposalId--) {
2059
+ const proposal = await goverannceContract.read.getProposal([proposalId]);
2060
+ if (isProposalFinal(proposal.state)) nonFinalProposals.push(proposalId);
2061
+ if (proposal.creationTime < Date.now() / 1e3 - 2592e3) break;
2062
+ }
2063
+ return nonFinalProposals;
2064
+ }
2019
2065
 
2020
2066
  // src/ecosystem/generated/etherscanExplorers.ts
2021
2067
  var etherscanExplorers = {
@@ -2910,7 +2956,7 @@ async function getSourceCode(params) {
2910
2956
  }
2911
2957
  return result[0];
2912
2958
  }
2913
- function parseApiSourceCode(sourceCode) {
2959
+ function parseEtherscanStyleSourceCode(sourceCode) {
2914
2960
  if (sourceCode.startsWith("{{") && sourceCode.endsWith("}}")) {
2915
2961
  sourceCode = sourceCode.substring(1, sourceCode.length - 1);
2916
2962
  }
@@ -2920,12 +2966,51 @@ function parseApiSourceCode(sourceCode) {
2920
2966
  // src/ecosystem/tenderly.ts
2921
2967
  var import_viem4 = require("viem");
2922
2968
  var TENDERLY_BASE_URL = "https://api.tenderly.co/api/v1";
2969
+ async function tenderly_deleteVnet(vnetId, { accountSlug, projectSlug, accessToken }) {
2970
+ return fetch(
2971
+ `${TENDERLY_BASE_URL}/account/${accountSlug}/project/${projectSlug}/vnets/${vnetId}`,
2972
+ {
2973
+ method: "DELETE",
2974
+ headers: new Headers({
2975
+ "Content-Type": "application/json",
2976
+ "X-Access-Key": accessToken
2977
+ })
2978
+ }
2979
+ );
2980
+ }
2981
+ async function tenderly_simVnet(vnetId, { accountSlug, projectSlug, accessToken }, body) {
2982
+ return (await fetch(
2983
+ // Note: this is subject to change and currently uses the internal api of tenderly
2984
+ `${TENDERLY_BASE_URL}/account/${accountSlug}/project/${projectSlug}/testnet/${vnetId}/simulate`,
2985
+ {
2986
+ method: "POST",
2987
+ body: JSON.stringify(body),
2988
+ headers: new Headers({
2989
+ "Content-Type": "application/json",
2990
+ "X-Access-Key": accessToken
2991
+ })
2992
+ }
2993
+ )).json();
2994
+ }
2995
+ async function tenderly_getVnet(slug, { accountSlug, projectSlug, accessToken }) {
2996
+ return (await fetch(
2997
+ `${TENDERLY_BASE_URL}/account/${accountSlug}/project/${projectSlug}/vnets?match_field=slug&match_type=prefix&keywords=${slug}`,
2998
+ {
2999
+ method: "GET",
3000
+ headers: new Headers({
3001
+ "Content-Type": "application/json",
3002
+ "X-Access-Key": accessToken
3003
+ })
3004
+ }
3005
+ )).json();
3006
+ }
2923
3007
  async function tenderly_createVnet({
2924
3008
  slug,
2925
3009
  displayName,
2926
3010
  baseChainId,
2927
3011
  forkChainId,
2928
- blockNumber
3012
+ blockNumber,
3013
+ force
2929
3014
  }, { accessToken, accountSlug, projectSlug }) {
2930
3015
  if (!accessToken) throw new Error("Tenderly access token not provided");
2931
3016
  if (!accountSlug) throw new Error("Tenderly account slug not provided");
@@ -2950,79 +3035,137 @@ async function tenderly_createVnet({
2950
3035
  verification_visibility: "bytecode"
2951
3036
  }
2952
3037
  };
2953
- const response = await fetch(
2954
- `${TENDERLY_BASE_URL}/account/${accountSlug}/project/${projectSlug}/vnets`,
2955
- {
2956
- method: "POST",
2957
- body: JSON.stringify(body),
2958
- headers: new Headers({
2959
- "Content-Type": "application/json",
2960
- "X-Access-Key": accessToken
2961
- })
2962
- }
2963
- );
2964
- const json = await response.json();
2965
- if (json.error) {
2966
- console.info(json.error);
3038
+ async function createVnet() {
3039
+ return (await fetch(
3040
+ `${TENDERLY_BASE_URL}/account/${accountSlug}/project/${projectSlug}/vnets`,
3041
+ {
3042
+ method: "POST",
3043
+ body: JSON.stringify(body),
3044
+ headers: new Headers({
3045
+ "Content-Type": "application/json",
3046
+ "X-Access-Key": accessToken
3047
+ })
3048
+ }
3049
+ )).json();
3050
+ }
3051
+ let response = await createVnet();
3052
+ if (response.error?.slug === "vnet_duplicate_key" && force) {
3053
+ const staleVnet = await tenderly_getVnet(slug, {
3054
+ accessToken,
3055
+ accountSlug,
3056
+ projectSlug
3057
+ });
3058
+ await tenderly_deleteVnet(staleVnet[0].id, {
3059
+ accessToken,
3060
+ accountSlug,
3061
+ projectSlug
3062
+ });
3063
+ response = await createVnet();
3064
+ }
3065
+ if (response.error) {
3066
+ console.info(response.error);
2967
3067
  throw new Error("Tenderly vnet could not be created");
2968
3068
  }
2969
3069
  return {
2970
- vnet: json,
3070
+ vnet: response,
2971
3071
  testClient: (0, import_viem4.createTestClient)({
2972
3072
  mode: "tenderly",
2973
- transport: (0, import_viem4.http)(json.rpcs[0].url)
3073
+ transport: (0, import_viem4.http)(response.rpcs[0].url)
2974
3074
  }),
2975
3075
  walletClient: (0, import_viem4.createWalletClient)({
2976
3076
  chain: { id: forkChainId },
2977
3077
  account: "0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9",
2978
- transport: (0, import_viem4.http)(json.rpcs[0].url)
3078
+ transport: (0, import_viem4.http)(response.rpcs[0].url)
2979
3079
  }),
2980
- simulate: (body2) => {
2981
- return fetch(
2982
- // Note: this is subject to change and currently uses the internal api of tenderly
2983
- `${TENDERLY_BASE_URL}/account/${accountSlug}/project/${projectSlug}/testnet/${json.id}/simulate`,
2984
- {
2985
- method: "POST",
2986
- body: JSON.stringify(body2),
2987
- headers: new Headers({
2988
- "Content-Type": "application/json",
2989
- "X-Access-Key": accessToken
2990
- })
2991
- }
2992
- );
2993
- },
2994
- delete: () => {
2995
- return fetch(
2996
- `${TENDERLY_BASE_URL}/account/${accountSlug}/project/${projectSlug}/vnets/${json.id}`,
2997
- {
2998
- method: "DELETE",
2999
- headers: new Headers({
3000
- "Content-Type": "application/json",
3001
- "X-Access-Key": accessToken
3002
- })
3003
- }
3004
- );
3005
- }
3080
+ simulate: (body2) => tenderly_simVnet(
3081
+ response.id,
3082
+ {
3083
+ accessToken,
3084
+ accountSlug,
3085
+ projectSlug
3086
+ },
3087
+ body2
3088
+ ),
3089
+ delete: () => tenderly_deleteVnet(response.id, {
3090
+ accessToken,
3091
+ accountSlug,
3092
+ projectSlug
3093
+ })
3006
3094
  };
3007
3095
  }
3008
3096
 
3097
+ // src/ecosystem/foundry.ts
3098
+ var import_node_child_process = require("child_process");
3099
+ var import_diff = require("diff");
3100
+ function foundry_getStandardJsonInput(input) {
3101
+ const output = JSON.parse(
3102
+ (0, import_node_child_process.execSync)(
3103
+ `forge verify-contract --show-standard-json-input --verifier etherscan 0x0000000000000000000000000000000000000000 ${input}`
3104
+ ).toString()
3105
+ );
3106
+ return output;
3107
+ }
3108
+ function foundry_getStorageLayout(input) {
3109
+ const output = JSON.parse(
3110
+ (0, import_node_child_process.execSync)(`forge inspect ${input} storage --json`).toString()
3111
+ );
3112
+ return output;
3113
+ }
3114
+ function cleanupFoundryStorageForDiffing(layout) {
3115
+ const cleanTypes = { ...layout.types };
3116
+ for (const key of Object.keys(cleanTypes)) {
3117
+ if (cleanTypes[key].members)
3118
+ cleanTypes[key].members = cleanTypes[key].members.map((member) => ({
3119
+ label: member.label,
3120
+ contract: member.contract.split(":")[1],
3121
+ offset: member.offset,
3122
+ slot: member.slot,
3123
+ type: member.type
3124
+ }));
3125
+ if (cleanTypes[key].value)
3126
+ cleanTypes[key].value = cleanTypes[cleanTypes[key].value];
3127
+ }
3128
+ const cleanStorage = layout.storage.map((storage) => ({
3129
+ label: storage.label,
3130
+ slot: storage.slot,
3131
+ offset: storage.offset,
3132
+ type: cleanTypes[storage.type],
3133
+ contract: storage.contract.split(":")[1]
3134
+ }));
3135
+ return cleanStorage;
3136
+ }
3137
+ function diffFoundryStorageLayout(layoutBefore, layoutAfter) {
3138
+ const beforeString = JSON.stringify(
3139
+ cleanupFoundryStorageForDiffing(layoutBefore),
3140
+ null,
3141
+ 2
3142
+ );
3143
+ const afterString = JSON.stringify(
3144
+ cleanupFoundryStorageForDiffing(layoutAfter),
3145
+ null,
3146
+ 2
3147
+ );
3148
+ return (0, import_diff.createPatch)("storage", beforeString, afterString);
3149
+ }
3150
+
3151
+ // src/ecosystem/event-db.ts
3152
+ var EVENT_DB = [];
3153
+
3009
3154
  // src/ecosystem/constants.ts
3010
3155
  var erc1967_ImplementationSlot = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
3011
3156
  var erc1967_AdminSlot = "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103";
3012
3157
 
3013
3158
  // src/operations/diffCode.ts
3014
- var import_diff = require("diff");
3159
+ var import_diff2 = require("diff");
3015
3160
  var import_standalone = require("prettier/standalone");
3016
3161
  var import_standalone2 = __toESM(require("prettier-plugin-solidity/standalone"));
3017
3162
  var prettierOptions = { parser: "solidity-parse", plugins: [import_standalone2.default] };
3018
- async function diffCode(codeBefore, codeAfter) {
3019
- const before = parseApiSourceCode(codeBefore);
3020
- const after = parseApiSourceCode(codeAfter);
3163
+ async function diffCode(before, after) {
3021
3164
  const changes = {};
3022
3165
  const settingsBefore = JSON.stringify(before.settings, null, 2);
3023
3166
  const settingsAfter = JSON.stringify(after.settings, null, 2);
3024
3167
  if (settingsBefore !== settingsAfter)
3025
- changes.settings = (0, import_diff.createPatch)("settings", settingsBefore, settingsAfter);
3168
+ changes.settings = (0, import_diff2.createPatch)("settings", settingsBefore, settingsAfter);
3026
3169
  const contractsBefore = await Promise.all(
3027
3170
  Object.entries(before.sources).map(async ([path, source]) => [
3028
3171
  path.replace(/^.*[\\/]/, ""),
@@ -3040,10 +3183,10 @@ async function diffCode(codeBefore, codeAfter) {
3040
3183
  for (const [name, path, source] of contractsBefore) {
3041
3184
  const indexAfter = contractsAfter.findIndex(([_name]) => _name === name);
3042
3185
  if (indexAfter === -1) {
3043
- changes[name] = (0, import_diff.createPatch)(path, source, "");
3186
+ changes[name] = (0, import_diff2.createPatch)(path, source, "");
3044
3187
  } else {
3045
3188
  if (source !== contractsAfter[indexAfter][2])
3046
- changes[name] = (0, import_diff.createTwoFilesPatch)(
3189
+ changes[name] = (0, import_diff2.createTwoFilesPatch)(
3047
3190
  path,
3048
3191
  contractsAfter[indexAfter][1],
3049
3192
  source,
@@ -3054,21 +3197,167 @@ async function diffCode(codeBefore, codeAfter) {
3054
3197
  for (const [name, path, source] of contractsAfter) {
3055
3198
  const indexAfter = contractsBefore.findIndex(([_name]) => _name === name);
3056
3199
  if (indexAfter === -1) {
3057
- changes[name] = (0, import_diff.createPatch)(path, "", source);
3200
+ changes[name] = (0, import_diff2.createPatch)(path, "", source);
3058
3201
  }
3059
3202
  }
3060
3203
  return changes;
3061
3204
  }
3205
+
3206
+ // src/seatbelt/logs.ts
3207
+ var import_viem5 = require("viem");
3208
+ function parseLogs({ logs, eventDb }) {
3209
+ const parsedLogs = logs.map((log) => {
3210
+ try {
3211
+ const decoded = (0, import_viem5.decodeEventLog)({
3212
+ data: log.data,
3213
+ topics: log.topics,
3214
+ abi: eventDb
3215
+ });
3216
+ return { ...log, ...decoded };
3217
+ } catch (e) {
3218
+ return log;
3219
+ }
3220
+ });
3221
+ return parsedLogs;
3222
+ }
3223
+
3224
+ // src/seatbelt/selfdestruct.ts
3225
+ var import_actions3 = require("viem/actions");
3226
+ var STOP = 0;
3227
+ var JUMPDEST = 91;
3228
+ var PUSH1 = 96;
3229
+ var PUSH32 = 127;
3230
+ var RETURN = 243;
3231
+ var REVERT = 253;
3232
+ var INVALID = 254;
3233
+ var SELFDESTRUCT = 255;
3234
+ var DELEGATECALL = 244;
3235
+ var isHalting = (opcode) => [STOP, RETURN, REVERT, INVALID, SELFDESTRUCT].includes(opcode);
3236
+ var isPUSH = (opcode) => opcode >= PUSH1 && opcode <= PUSH32;
3237
+ var SelfdestuctCheckState = /* @__PURE__ */ ((SelfdestuctCheckState2) => {
3238
+ SelfdestuctCheckState2[SelfdestuctCheckState2["TRUSTED"] = 0] = "TRUSTED";
3239
+ SelfdestuctCheckState2[SelfdestuctCheckState2["EOA"] = 1] = "EOA";
3240
+ SelfdestuctCheckState2[SelfdestuctCheckState2["EMPTY"] = 2] = "EMPTY";
3241
+ SelfdestuctCheckState2[SelfdestuctCheckState2["DELEGATECALL"] = 3] = "DELEGATECALL";
3242
+ SelfdestuctCheckState2[SelfdestuctCheckState2["SAFE"] = 4] = "SAFE";
3243
+ SelfdestuctCheckState2[SelfdestuctCheckState2["SELF_DESTRUCT"] = 5] = "SELF_DESTRUCT";
3244
+ return SelfdestuctCheckState2;
3245
+ })(SelfdestuctCheckState || {});
3246
+ async function checkForSelfdestruct(client, addresses, trustedAddresses) {
3247
+ const result = [];
3248
+ for (const address of addresses) {
3249
+ if (trustedAddresses.includes(address)) {
3250
+ result.push({ address, state: 0 /* TRUSTED */ });
3251
+ continue;
3252
+ }
3253
+ const code = await (0, import_actions3.getBytecode)(client, { address });
3254
+ if (!code) {
3255
+ const nonce = await (0, import_actions3.getTransactionCount)(client, { address });
3256
+ if (nonce > 0) result.push({ address, state: 1 /* EOA */ });
3257
+ else result.push({ address, state: 2 /* EMPTY */ });
3258
+ continue;
3259
+ }
3260
+ const bytecode = Buffer.from(code.substring(2), "hex");
3261
+ const { delegatecall, selfDestruct } = checkCode(bytecode);
3262
+ if (selfDestruct) {
3263
+ result.push({ address, state: 5 /* SELF_DESTRUCT */ });
3264
+ } else if (delegatecall) {
3265
+ result.push({ address, state: 3 /* DELEGATECALL */ });
3266
+ } else {
3267
+ result.push({ address, state: 4 /* SAFE */ });
3268
+ }
3269
+ }
3270
+ return result;
3271
+ }
3272
+ function checkCode(bytecode) {
3273
+ let halted = false;
3274
+ let delegatecall = false;
3275
+ for (let index = 0; index < bytecode.length; index++) {
3276
+ const opcode = bytecode[index];
3277
+ if (opcode === SELFDESTRUCT && !halted) {
3278
+ return { halted, delegatecall, selfDestruct: true };
3279
+ }
3280
+ if (opcode === DELEGATECALL && !halted) {
3281
+ delegatecall = true;
3282
+ } else if (opcode === JUMPDEST) {
3283
+ halted = false;
3284
+ } else if (isHalting(opcode)) {
3285
+ halted = true;
3286
+ } else if (isPUSH(opcode)) {
3287
+ index += opcode - PUSH1 + 1;
3288
+ }
3289
+ }
3290
+ return { halted, delegatecall, selfDestruct: false };
3291
+ }
3292
+
3293
+ // src/seatbelt/verified.ts
3294
+ function getVerificationStatus({
3295
+ chainId,
3296
+ addresses,
3297
+ contractDb,
3298
+ apiKey,
3299
+ apiUrl
3300
+ }) {
3301
+ return Promise.all(
3302
+ addresses.map(async (address) => {
3303
+ if (contractDb[address])
3304
+ return {
3305
+ address,
3306
+ name: contractDb[address],
3307
+ status: 0 /* CACHE */
3308
+ };
3309
+ try {
3310
+ const code = await getSourceCode({ chainId, address, apiKey, apiUrl });
3311
+ return {
3312
+ address,
3313
+ name: code.ContractName,
3314
+ status: 1 /* NEW */
3315
+ };
3316
+ } catch (e) {
3317
+ return {
3318
+ address,
3319
+ status: 2 /* ERROR */
3320
+ };
3321
+ }
3322
+ })
3323
+ );
3324
+ }
3325
+
3326
+ // src/seatbelt/tenderly-report.ts
3327
+ async function renderTenderlyReport({
3328
+ client,
3329
+ sim
3330
+ }) {
3331
+ const logs = parseLogs({
3332
+ logs: (sim.transaction.transaction_info.logs || []).map((l) => l.raw),
3333
+ eventDb: EVENT_DB
3334
+ });
3335
+ const selfDestruct = checkForSelfdestruct(
3336
+ client,
3337
+ sim.transaction.addresses,
3338
+ []
3339
+ // trusted addresses
3340
+ );
3341
+ const verified = getVerificationStatus({
3342
+ chainId: client.chain.id,
3343
+ addresses: sim.transaction.addresses,
3344
+ contractDb: {}
3345
+ });
3346
+ return logs;
3347
+ }
3062
3348
  // Annotate the CommonJS export names for ESM import in node:
3063
3349
  0 && (module.exports = {
3350
+ EVENT_DB,
3064
3351
  HALF_RAY,
3065
3352
  HALF_WAD,
3066
3353
  HUMAN_READABLE_PAYLOAD_STATE,
3067
3354
  HUMAN_READABLE_PROPOSAL_STATE,
3068
3355
  LTV_PRECISION,
3069
3356
  PayloadState,
3357
+ ProposalState,
3070
3358
  RAY,
3071
3359
  SECONDS_PER_YEAR,
3360
+ SelfdestuctCheckState,
3072
3361
  WAD,
3073
3362
  WAD_RAY_RATIO,
3074
3363
  bitmapToIndexes,
@@ -3076,12 +3365,16 @@ async function diffCode(codeBefore, codeAfter) {
3076
3365
  calculateCompoundedInterest,
3077
3366
  calculateHealthFactorFromBalances,
3078
3367
  calculateLinearInterest,
3368
+ checkForSelfdestruct,
3079
3369
  decodeReserveConfiguration,
3080
3370
  decodeReserveConfigurationV2,
3081
3371
  decodeUserConfiguration,
3082
3372
  diffCode,
3373
+ diffFoundryStorageLayout,
3083
3374
  erc1967_AdminSlot,
3084
3375
  erc1967_ImplementationSlot,
3376
+ foundry_getStandardJsonInput,
3377
+ foundry_getStorageLayout,
3085
3378
  getBits,
3086
3379
  getCurrentDebtBalance,
3087
3380
  getCurrentLiquidityBalance,
@@ -3089,18 +3382,26 @@ async function diffCode(codeBefore, codeAfter) {
3089
3382
  getGovernance,
3090
3383
  getMarketReferenceCurrencyAndUsdBalance,
3091
3384
  getNonFinalizedPayloads,
3385
+ getNonFinalizedProposals,
3092
3386
  getNormalizedDebt,
3093
3387
  getNormalizedIncome,
3094
3388
  getPayloadsController,
3095
3389
  getSourceCode,
3390
+ isPayloadFinal,
3391
+ isProposalFinal,
3096
3392
  makePayloadExecutableOnTestClient,
3097
3393
  makeProposalExecutableOnTestClient,
3098
- parseApiSourceCode,
3394
+ parseEtherscanStyleSourceCode,
3395
+ parseLogs,
3099
3396
  rayDiv,
3100
3397
  rayMul,
3101
3398
  rayToWad,
3399
+ renderTenderlyReport,
3102
3400
  setBits,
3103
3401
  tenderly_createVnet,
3402
+ tenderly_deleteVnet,
3403
+ tenderly_getVnet,
3404
+ tenderly_simVnet,
3104
3405
  wadDiv,
3105
3406
  wadToRay
3106
3407
  });