@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.d.mts +104 -19
- package/dist/index.d.ts +104 -19
- package/dist/index.js +368 -67
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +353 -65
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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 (
|
|
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 (
|
|
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
|
-
[
|
|
1976
|
-
[
|
|
1977
|
-
[
|
|
1978
|
-
[
|
|
1979
|
-
[
|
|
1980
|
-
[
|
|
1981
|
-
[
|
|
1982
|
-
[
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
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:
|
|
3070
|
+
vnet: response,
|
|
2971
3071
|
testClient: (0, import_viem4.createTestClient)({
|
|
2972
3072
|
mode: "tenderly",
|
|
2973
|
-
transport: (0, import_viem4.http)(
|
|
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)(
|
|
3078
|
+
transport: (0, import_viem4.http)(response.rpcs[0].url)
|
|
2979
3079
|
}),
|
|
2980
|
-
simulate: (body2) =>
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
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
|
|
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(
|
|
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,
|
|
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,
|
|
3186
|
+
changes[name] = (0, import_diff2.createPatch)(path, source, "");
|
|
3044
3187
|
} else {
|
|
3045
3188
|
if (source !== contractsAfter[indexAfter][2])
|
|
3046
|
-
changes[name] = (0,
|
|
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,
|
|
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
|
-
|
|
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
|
});
|