Add Sepolia funding threshold helper for smoke runs
Some checks are pending
check / contracts (push) Waiting to run
Some checks are pending
check / contracts (push) Waiting to run
This commit is contained in:
parent
1dd74d57e6
commit
af4f7796e7
12
README.md
12
README.md
@ -44,6 +44,7 @@ Use a Hardhat-supported Node runtime (`20.x` recommended).
|
||||
8. `npm run deploy:entitlement:mainnet`
|
||||
9. `npm run update:membership:price:sepolia`
|
||||
10. `npm run update:membership:price:mainnet`
|
||||
11. `npm run smoke:funding:sepolia`
|
||||
|
||||
`make check` wraps build + tests.
|
||||
|
||||
@ -91,6 +92,9 @@ Smoke flow optional vars:
|
||||
9. `E2E_DEVICE_ID`
|
||||
10. `E2E_PLATFORM`
|
||||
11. `E2E_LAUNCHER_VERSION`
|
||||
12. `E2E_GAS_LIMIT` (optional fixed gas limit, default `300000`)
|
||||
13. `E2E_GAS_PRICE_WEI` (optional fixed gas price)
|
||||
14. `SMOKE_MIN_GAS_PRICE_WEI` (optional threshold floor for funding estimator, default `1000000000`)
|
||||
|
||||
Example (Sepolia):
|
||||
|
||||
@ -117,6 +121,14 @@ export ENTITLEMENT_CONTRACT_ADDRESS="0x..."
|
||||
npm run verify:offers:sepolia
|
||||
```
|
||||
|
||||
Sepolia smoke funding threshold from live fee data:
|
||||
|
||||
```bash
|
||||
cd /Users/vsg/Documents/VSG\ Codex/contracts
|
||||
export BASE_SEPOLIA_RPC_URL="https://base-sepolia.g.alchemy.com/v2/<key>"
|
||||
npm run smoke:funding:sepolia
|
||||
```
|
||||
|
||||
## Boundary
|
||||
|
||||
Contracts are settlement primitives. Runtime execution remains off-chain and fail-closed by entitlement state.
|
||||
|
||||
@ -16,7 +16,8 @@
|
||||
"deploy:entitlement:mainnet": "hardhat run scripts/deploy-entitlement.cjs --network base",
|
||||
"smoke:e2e:sepolia": "node scripts/e2e-membership-flow.cjs",
|
||||
"smoke:e2e:controlplane:sepolia": "node scripts/e2e-control-plane-flow.cjs",
|
||||
"verify:offers:sepolia": "node scripts/verify-offer-config-readback.cjs"
|
||||
"verify:offers:sepolia": "node scripts/verify-offer-config-readback.cjs",
|
||||
"smoke:funding:sepolia": "node scripts/report-smoke-funding-threshold.cjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomiclabs/hardhat-ethers": "^2.2.3",
|
||||
|
||||
@ -7,7 +7,7 @@ const CHAIN_ID = Number((process.env.SECRET_API_CHAIN_ID || "84532").trim());
|
||||
const PRIVATE_KEY = (process.env.DEPLOYER_PRIVATE_KEY || "").trim();
|
||||
const RPC_URL = (process.env.BASE_SEPOLIA_RPC_URL || "").trim();
|
||||
const GAS_PRICE_WEI = (process.env.E2E_GAS_PRICE_WEI || "").trim();
|
||||
const GAS_LIMIT = (process.env.E2E_GAS_LIMIT || "500000").trim();
|
||||
const GAS_LIMIT = (process.env.E2E_GAS_LIMIT || "300000").trim();
|
||||
|
||||
const OFFER_ID = (process.env.E2E_OFFER_ID || "edut.workspace.core").trim();
|
||||
const ORG_ROOT_ID = (process.env.E2E_ORG_ROOT_ID || "org.e2e.workspace").trim();
|
||||
|
||||
98
scripts/report-smoke-funding-threshold.cjs
Normal file
98
scripts/report-smoke-funding-threshold.cjs
Normal file
@ -0,0 +1,98 @@
|
||||
const { ethers } = require("ethers");
|
||||
|
||||
const RPC_URL = (process.env.BASE_SEPOLIA_RPC_URL || "").trim();
|
||||
const MEMBERSHIP_GAS = Number.parseInt((process.env.SMOKE_MEMBERSHIP_GAS || "160000").trim(), 10);
|
||||
const CHECKOUT_GAS = Number.parseInt((process.env.SMOKE_CHECKOUT_GAS || "220000").trim(), 10);
|
||||
const SAFETY_BPS = Number.parseInt((process.env.SMOKE_SAFETY_BPS || "15000").trim(), 10); // 1.5x
|
||||
const MIN_GAS_PRICE_WEI = (process.env.SMOKE_MIN_GAS_PRICE_WEI || "1000000000").trim(); // 1 gwei floor
|
||||
|
||||
function required(name, value) {
|
||||
if (!value) {
|
||||
throw new Error(`Missing required env: ${name}`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function validatePositiveInt(name, value) {
|
||||
if (!Number.isFinite(value) || value <= 0) {
|
||||
throw new Error(`${name} must be a positive integer`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function maxBigInt(values) {
|
||||
let out = values[0];
|
||||
for (let i = 1; i < values.length; i += 1) {
|
||||
if (values[i].gt(out)) {
|
||||
out = values[i];
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function applySafety(valueWei) {
|
||||
return valueWei.mul(SAFETY_BPS).add(9999).div(10000);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
required("BASE_SEPOLIA_RPC_URL", RPC_URL);
|
||||
validatePositiveInt("SMOKE_MEMBERSHIP_GAS", MEMBERSHIP_GAS);
|
||||
validatePositiveInt("SMOKE_CHECKOUT_GAS", CHECKOUT_GAS);
|
||||
validatePositiveInt("SMOKE_SAFETY_BPS", SAFETY_BPS);
|
||||
const minGasPrice = ethers.BigNumber.from(required("SMOKE_MIN_GAS_PRICE_WEI", MIN_GAS_PRICE_WEI));
|
||||
if (minGasPrice.lte(0)) {
|
||||
throw new Error("SMOKE_MIN_GAS_PRICE_WEI must be > 0");
|
||||
}
|
||||
|
||||
const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
|
||||
const feeData = await provider.getFeeData();
|
||||
const feeCandidates = [feeData.gasPrice, feeData.maxFeePerGas, minGasPrice].filter(Boolean);
|
||||
if (feeCandidates.length === 0) {
|
||||
throw new Error("Unable to resolve gas price from provider");
|
||||
}
|
||||
const gasPrice = maxBigInt(feeCandidates);
|
||||
|
||||
const membershipWei = gasPrice.mul(MEMBERSHIP_GAS);
|
||||
const checkoutWei = gasPrice.mul(CHECKOUT_GAS);
|
||||
const freshWalletBaseWei = membershipWei.add(checkoutWei);
|
||||
const activeWalletBaseWei = checkoutWei;
|
||||
const freshWalletRecommendedWei = applySafety(freshWalletBaseWei);
|
||||
const activeWalletRecommendedWei = applySafety(activeWalletBaseWei);
|
||||
|
||||
const report = {
|
||||
chain: "base-sepolia",
|
||||
gas_price_sources: {
|
||||
provider_gas_price_wei: feeData.gasPrice ? feeData.gasPrice.toString() : null,
|
||||
provider_max_fee_per_gas_wei: feeData.maxFeePerGas ? feeData.maxFeePerGas.toString() : null,
|
||||
floor_gas_price_wei: minGasPrice.toString(),
|
||||
},
|
||||
gas_price_wei: gasPrice.toString(),
|
||||
gas_price_gwei: ethers.utils.formatUnits(gasPrice, "gwei"),
|
||||
gas_budgets: {
|
||||
membership: MEMBERSHIP_GAS,
|
||||
checkout: CHECKOUT_GAS,
|
||||
},
|
||||
safety_multiplier: `${(SAFETY_BPS / 10000).toFixed(2)}x`,
|
||||
thresholds: {
|
||||
fresh_wallet_membership_plus_checkout: {
|
||||
base_wei: freshWalletBaseWei.toString(),
|
||||
base_eth: ethers.utils.formatEther(freshWalletBaseWei),
|
||||
recommended_wei: freshWalletRecommendedWei.toString(),
|
||||
recommended_eth: ethers.utils.formatEther(freshWalletRecommendedWei),
|
||||
},
|
||||
active_wallet_checkout_only: {
|
||||
base_wei: activeWalletBaseWei.toString(),
|
||||
base_eth: ethers.utils.formatEther(activeWalletBaseWei),
|
||||
recommended_wei: activeWalletRecommendedWei.toString(),
|
||||
recommended_eth: ethers.utils.formatEther(activeWalletRecommendedWei),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(report, null, 2));
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err.message || err);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user