skillpp 0.1.0
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/COMPATIBILITY.md +58 -0
- package/LICENSE +21 -0
- package/README.md +307 -0
- package/README.zh-CN.md +307 -0
- package/SKILL.md +490 -0
- package/adapters/binance-ai.md +22 -0
- package/adapters/claude.md +21 -0
- package/adapters/gemini.md +26 -0
- package/adapters/gpt.md +28 -0
- package/adapters/kimi.md +26 -0
- package/adapters/mimo.md +22 -0
- package/adapters/openclaw.md +29 -0
- package/assets/skillpp-banner.png +0 -0
- package/package.json +59 -0
- package/pipelines.md +310 -0
- package/prompts/newbie-mode.md +48 -0
- package/prompts/router-prompt.md +32 -0
- package/prompts/universal-system-prompt.md +41 -0
- package/registry.md +209 -0
- package/rules.md +323 -0
- package/schemas/audit.schema.json +67 -0
- package/schemas/checkpoint.schema.json +86 -0
- package/schemas/handoff.schema.json +82 -0
- package/schemas/token.schema.json +36 -0
- package/scripts/compatibility-check.mjs +130 -0
- package/scripts/selftest.mjs +384 -0
- package/scripts/skillpp.mjs +448 -0
- package/scripts/validate-skillpp.mjs +140 -0
- package/skillpp.manifest.json +714 -0
- package/skills/audit-plus/SKILL.md +612 -0
- package/skills/binance/binance/CHANGELOG.md +112 -0
- package/skills/binance/binance/LICENSE.md +9 -0
- package/skills/binance/binance/SKILL.md +69 -0
- package/skills/binance/binance/references/algo.md +21 -0
- package/skills/binance/binance/references/alpha.md +9 -0
- package/skills/binance/binance/references/auth.md +32 -0
- package/skills/binance/binance/references/c2c.md +5 -0
- package/skills/binance/binance/references/convert.md +19 -0
- package/skills/binance/binance/references/copy-trading.md +6 -0
- package/skills/binance/binance/references/crypto-loan.md +27 -0
- package/skills/binance/binance/references/derivatives-options-streams.md +25 -0
- package/skills/binance/binance/references/derivatives-options.md +85 -0
- package/skills/binance/binance/references/derivatives-portfolio-margin-pro-streams.md +5 -0
- package/skills/binance/binance/references/derivatives-portfolio-margin-pro.md +34 -0
- package/skills/binance/binance/references/derivatives-portfolio-margin-streams.md +5 -0
- package/skills/binance/binance/references/derivatives-portfolio-margin.md +146 -0
- package/skills/binance/binance/references/dual-investment.md +15 -0
- package/skills/binance/binance/references/fiat.md +9 -0
- package/skills/binance/binance/references/futures-coin-streams.md +29 -0
- package/skills/binance/binance/references/futures-coin.md +109 -0
- package/skills/binance/binance/references/futures-usds-streams.md +35 -0
- package/skills/binance/binance/references/futures-usds.md +144 -0
- package/skills/binance/binance/references/gift-card.md +10 -0
- package/skills/binance/binance/references/margin-trading-streams.md +6 -0
- package/skills/binance/binance/references/margin-trading.md +101 -0
- package/skills/binance/binance/references/mining.md +17 -0
- package/skills/binance/binance/references/pay.md +5 -0
- package/skills/binance/binance/references/rebate.md +5 -0
- package/skills/binance/binance/references/simple-earn.md +56 -0
- package/skills/binance/binance/references/spot-streams.md +25 -0
- package/skills/binance/binance/references/spot.md +114 -0
- package/skills/binance/binance/references/staking.md +59 -0
- package/skills/binance/binance/references/sub-account.md +67 -0
- package/skills/binance/binance/references/vip-loan.md +27 -0
- package/skills/binance/binance/references/wallet.md +75 -0
- package/skills/binance/fiat/CHANGELOG.md +11 -0
- package/skills/binance/fiat/LICENSE.md +9 -0
- package/skills/binance/fiat/SKILL.md +169 -0
- package/skills/binance/fiat/references/authentication.md +126 -0
- package/skills/binance/fiat/references/sapi-endpoints.md +217 -0
- package/skills/binance/onchain-pay/.local.md.example +10 -0
- package/skills/binance/onchain-pay/CHANGELOG.md +20 -0
- package/skills/binance/onchain-pay/LICENSE.md +9 -0
- package/skills/binance/onchain-pay/SKILL.md +466 -0
- package/skills/binance/onchain-pay/references/authentication.md +92 -0
- package/skills/binance/onchain-pay/scripts/sign_and_call.sh +52 -0
- package/skills/binance/p2p/CHANGELOG.md +33 -0
- package/skills/binance/p2p/LICENSE.md +9 -0
- package/skills/binance/p2p/SKILL.md +1082 -0
- package/skills/binance/p2p/references/agent-sapi-api.md +795 -0
- package/skills/binance/p2p/references/authentication.md +100 -0
- package/skills/binance/payment/SKILL.md +824 -0
- package/skills/binance/payment/common.py +560 -0
- package/skills/binance/payment/payment_skill.py +86 -0
- package/skills/binance/payment/receive.py +109 -0
- package/skills/binance/payment/references/setup-guide.md +77 -0
- package/skills/binance/payment/requirements.txt +4 -0
- package/skills/binance/payment/send.py +952 -0
- package/skills/binance/payment/send_extension/__init__.py +43 -0
- package/skills/binance/payment/send_extension/base.py +48 -0
- package/skills/binance/payment/send_extension/c2c.py +193 -0
- package/skills/binance/payment/send_extension/pix.py +316 -0
- package/skills/binance/square-post/README.md +62 -0
- package/skills/binance/square-post/SKILL.md +171 -0
- package/skills/binance/square-post/scripts/lib.mjs +175 -0
- package/skills/binance/square-post/scripts/post-image.mjs +80 -0
- package/skills/binance/square-post/scripts/post-text.mjs +41 -0
- package/skills/binance/square-post/scripts/post-video.mjs +110 -0
- package/skills/binance/square-post/scripts/save-key.mjs +34 -0
- package/skills/binance-web3/binance-agentic-wallet/SKILL.md +150 -0
- package/skills/binance-web3/binance-agentic-wallet/references/authentication.md +136 -0
- package/skills/binance-web3/binance-agentic-wallet/references/limit-order.md +204 -0
- package/skills/binance-web3/binance-agentic-wallet/references/market-order.md +179 -0
- package/skills/binance-web3/binance-agentic-wallet/references/prediction.md +489 -0
- package/skills/binance-web3/binance-agentic-wallet/references/preflight.md +66 -0
- package/skills/binance-web3/binance-agentic-wallet/references/security.md +47 -0
- package/skills/binance-web3/binance-agentic-wallet/references/send.md +53 -0
- package/skills/binance-web3/binance-agentic-wallet/references/wallet-setting.md +86 -0
- package/skills/binance-web3/binance-agentic-wallet/references/wallet-view.md +312 -0
- package/skills/binance-web3/binance-agentic-wallet/references/x402-payment.md +259 -0
- package/skills/binance-web3/binance-tokenized-securities-info/SKILL.md +613 -0
- package/skills/binance-web3/crypto-market-rank/SKILL.md +91 -0
- package/skills/binance-web3/crypto-market-rank/references/cli.md +219 -0
- package/skills/binance-web3/crypto-market-rank/scripts/cli.mjs +149 -0
- package/skills/binance-web3/meme-rush/SKILL.md +72 -0
- package/skills/binance-web3/meme-rush/references/cli.md +158 -0
- package/skills/binance-web3/meme-rush/scripts/cli.mjs +101 -0
- package/skills/binance-web3/query-address-info/SKILL.md +61 -0
- package/skills/binance-web3/query-address-info/references/cli.md +56 -0
- package/skills/binance-web3/query-address-info/scripts/cli.mjs +132 -0
- package/skills/binance-web3/query-token-audit/SKILL.md +162 -0
- package/skills/binance-web3/query-token-info/SKILL.md +83 -0
- package/skills/binance-web3/query-token-info/references/cli.md +135 -0
- package/skills/binance-web3/query-token-info/scripts/cli.mjs +112 -0
- package/skills/binance-web3/trading-signal/SKILL.md +66 -0
- package/skills/binance-web3/trading-signal/references/cli.md +90 -0
- package/skills/binance-web3/trading-signal/scripts/cli.mjs +92 -0
- package/skills/four-meme/four-guard/API-Contract-TaxToken.md +277 -0
- package/skills/four-meme/four-guard/API-CreateToken.02-02-2026.md +285 -0
- package/skills/four-meme/four-guard/API-Documents.03-03-2026.md +789 -0
- package/skills/four-meme/four-guard/AgentIdentifier.abi +585 -0
- package/skills/four-meme/four-guard/README.md +21 -0
- package/skills/four-meme/four-guard/SKILL.md +31 -0
- package/skills/four-meme/four-guard/TaxToken.abi +969 -0
- package/skills/four-meme/four-guard/TokenIdentifierSample.js_ +81 -0
- package/skills/four-meme/four-guard/TokenIdentifierSample.sol +69 -0
- package/skills/four-meme/four-guard/TokenManager.lite.abi +836 -0
- package/skills/four-meme/four-guard/TokenManager2.lite.abi +2325 -0
- package/skills/four-meme/four-guard/TokenManagerHelper3.abi +999 -0
- package/skills/four-meme/four-guard/go.mod +36 -0
- package/skills/four-meme/four-guard/go.sum +127 -0
- package/skills/four-meme/four-guard/main.go +183 -0
- package/skills/four-meme/four-meme-ai/SKILL.md +31 -0
- package/skills/four-meme/four-meme-ai/references/agent-creator-and-wallets.md +87 -0
- package/skills/four-meme/four-meme-ai/references/api-create-token.md +55 -0
- package/skills/four-meme/four-meme-ai/references/contract-addresses.md +47 -0
- package/skills/four-meme/four-meme-ai/references/create-token-scripts.md +131 -0
- package/skills/four-meme/four-meme-ai/references/errors.md +29 -0
- package/skills/four-meme/four-meme-ai/references/event-listening.md +75 -0
- package/skills/four-meme/four-meme-ai/references/execute-trade.md +31 -0
- package/skills/four-meme/four-meme-ai/references/tax-token-query.md +38 -0
- package/skills/four-meme/four-meme-ai/references/token-query-api.md +44 -0
- package/skills/four-meme/four-meme-ai/references/token-tax-info.md +77 -0
- package/skills/four-meme/four-meme-ai/scripts/8004-balance.ts +52 -0
- package/skills/four-meme/four-meme-ai/scripts/8004-register.ts +108 -0
- package/skills/four-meme/four-meme-ai/scripts/create-token-api.ts +321 -0
- package/skills/four-meme/four-meme-ai/scripts/create-token-chain.ts +102 -0
- package/skills/four-meme/four-meme-ai/scripts/create-token-instant.ts +106 -0
- package/skills/four-meme/four-meme-ai/scripts/execute-buy.ts +198 -0
- package/skills/four-meme/four-meme-ai/scripts/execute-sell.ts +150 -0
- package/skills/four-meme/four-meme-ai/scripts/get-public-config.ts +25 -0
- package/skills/four-meme/four-meme-ai/scripts/get-recent-events.ts +76 -0
- package/skills/four-meme/four-meme-ai/scripts/get-tax-token-info.ts +69 -0
- package/skills/four-meme/four-meme-ai/scripts/get-token-info.ts +94 -0
- package/skills/four-meme/four-meme-ai/scripts/quote-buy.ts +85 -0
- package/skills/four-meme/four-meme-ai/scripts/quote-sell.ts +66 -0
- package/skills/four-meme/four-meme-ai/scripts/send-token.ts +98 -0
- package/skills/four-meme/four-meme-ai/scripts/token-get.ts +31 -0
- package/skills/four-meme/four-meme-ai/scripts/token-list.ts +134 -0
- package/skills/four-meme/four-meme-ai/scripts/token-rankings.ts +162 -0
- package/skills/four-meme/four-meme-ai/scripts/verify-events.ts +47 -0
- package/skills/four-meme/four-meme-integration/SKILL.md +374 -0
- package/skills/four-meme/four-meme-integration/references/agent-creator-and-wallets.md +87 -0
- package/skills/four-meme/four-meme-integration/references/api-create-token.md +55 -0
- package/skills/four-meme/four-meme-integration/references/contract-addresses.md +47 -0
- package/skills/four-meme/four-meme-integration/references/create-token-scripts.md +131 -0
- package/skills/four-meme/four-meme-integration/references/errors.md +29 -0
- package/skills/four-meme/four-meme-integration/references/event-listening.md +75 -0
- package/skills/four-meme/four-meme-integration/references/execute-trade.md +31 -0
- package/skills/four-meme/four-meme-integration/references/tax-token-query.md +38 -0
- package/skills/four-meme/four-meme-integration/references/token-query-api.md +44 -0
- package/skills/four-meme/four-meme-integration/references/token-tax-info.md +77 -0
- package/skills/four-meme/four-meme-integration/scripts/8004-balance.ts +52 -0
- package/skills/four-meme/four-meme-integration/scripts/8004-register.ts +108 -0
- package/skills/four-meme/four-meme-integration/scripts/create-token-api.ts +321 -0
- package/skills/four-meme/four-meme-integration/scripts/create-token-chain.ts +102 -0
- package/skills/four-meme/four-meme-integration/scripts/create-token-instant.ts +106 -0
- package/skills/four-meme/four-meme-integration/scripts/execute-buy.ts +198 -0
- package/skills/four-meme/four-meme-integration/scripts/execute-sell.ts +150 -0
- package/skills/four-meme/four-meme-integration/scripts/get-public-config.ts +25 -0
- package/skills/four-meme/four-meme-integration/scripts/get-recent-events.ts +76 -0
- package/skills/four-meme/four-meme-integration/scripts/get-tax-token-info.ts +69 -0
- package/skills/four-meme/four-meme-integration/scripts/get-token-info.ts +94 -0
- package/skills/four-meme/four-meme-integration/scripts/quote-buy.ts +85 -0
- package/skills/four-meme/four-meme-integration/scripts/quote-sell.ts +66 -0
- package/skills/four-meme/four-meme-integration/scripts/send-token.ts +98 -0
- package/skills/four-meme/four-meme-integration/scripts/token-get.ts +31 -0
- package/skills/four-meme/four-meme-integration/scripts/token-list.ts +134 -0
- package/skills/four-meme/four-meme-integration/scripts/token-rankings.ts +162 -0
- package/skills/four-meme/four-meme-integration/scripts/verify-events.ts +47 -0
- package/skills/skillpp/contract-profiler/SKILL.md +118 -0
- package/skills/skillpp/newbie-tutor/SKILL.md +85 -0
- package/skills/skillpp/opportunity-board/SKILL.md +87 -0
- package/skills/skillpp/risk-fusion/SKILL.md +146 -0
- package/skills/skillpp/scam-pattern-lab/SKILL.md +115 -0
- package/skills/skillpp/wallet-doctor/SKILL.md +119 -0
- package/skills/skillpp/watchtower/SKILL.md +72 -0
- package/tests/compatibility/v0.1.0.json +117 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Four.meme - sell quote via TokenManagerHelper3.trySell (BSC only).
|
|
4
|
+
* Usage: npx tsx quote-sell.ts <tokenAddress> <amountWei>
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { createPublicClient, http } from 'viem';
|
|
8
|
+
import { bsc } from 'viem/chains';
|
|
9
|
+
|
|
10
|
+
const HELPER_ADDRESS = '0xF251F83e40a78868FcfA3FA4599Dad6494E46034' as const;
|
|
11
|
+
|
|
12
|
+
const HELPER_ABI = [
|
|
13
|
+
{
|
|
14
|
+
name: 'trySell',
|
|
15
|
+
type: 'function',
|
|
16
|
+
stateMutability: 'view',
|
|
17
|
+
inputs: [
|
|
18
|
+
{ name: 'token', type: 'address' },
|
|
19
|
+
{ name: 'amount', type: 'uint256' },
|
|
20
|
+
],
|
|
21
|
+
outputs: [
|
|
22
|
+
{ name: 'tokenManager', type: 'address' },
|
|
23
|
+
{ name: 'quote', type: 'address' },
|
|
24
|
+
{ name: 'funds', type: 'uint256' },
|
|
25
|
+
{ name: 'fee', type: 'uint256' },
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
] as const;
|
|
29
|
+
|
|
30
|
+
const RPC_URL = process.env.BSC_RPC_URL || 'https://bsc-dataseed.binance.org';
|
|
31
|
+
|
|
32
|
+
async function main() {
|
|
33
|
+
const tokenAddress = process.argv[2] as `0x${string}`;
|
|
34
|
+
const amountWei = BigInt(process.argv[3] ?? '0');
|
|
35
|
+
|
|
36
|
+
if (!tokenAddress) {
|
|
37
|
+
console.error('Usage: npx tsx quote-sell.ts <tokenAddress> <amountWei>');
|
|
38
|
+
console.error('BSC only.');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const client = createPublicClient({
|
|
43
|
+
chain: bsc,
|
|
44
|
+
transport: http(RPC_URL),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const [tokenManager, quote, funds, fee] = await client.readContract({
|
|
48
|
+
address: HELPER_ADDRESS,
|
|
49
|
+
abi: HELPER_ABI,
|
|
50
|
+
functionName: 'trySell',
|
|
51
|
+
args: [tokenAddress, amountWei],
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const out = {
|
|
55
|
+
tokenManager,
|
|
56
|
+
quote: quote === '0x0000000000000000000000000000000000000000' ? 'native' : quote,
|
|
57
|
+
funds: funds.toString(),
|
|
58
|
+
fee: fee.toString(),
|
|
59
|
+
};
|
|
60
|
+
console.log(JSON.stringify(out, null, 2));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
main().catch((e) => {
|
|
64
|
+
console.error(e.message || e);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Four.meme - send BNB or ERC20 from current wallet to a target address (BSC).
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* npx tsx send-token.ts <toAddress> <amountWei> [tokenAddress]
|
|
7
|
+
* - toAddress: recipient wallet address (0x...)
|
|
8
|
+
* - amountWei: amount in wei (for BNB or token decimals)
|
|
9
|
+
* - tokenAddress: optional; omit or use "BNB" / "0x0" for native BNB; otherwise ERC20 token contract address
|
|
10
|
+
*
|
|
11
|
+
* Env: PRIVATE_KEY. Optional: BSC_RPC_URL.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { createWalletClient, http, parseAbi } from 'viem';
|
|
15
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
16
|
+
import { bsc } from 'viem/chains';
|
|
17
|
+
|
|
18
|
+
const ZERO = '0x0000000000000000000000000000000000000000' as const;
|
|
19
|
+
|
|
20
|
+
const ERC20_ABI = parseAbi([
|
|
21
|
+
'function transfer(address to, uint256 amount) returns (bool)',
|
|
22
|
+
]);
|
|
23
|
+
|
|
24
|
+
function isAddress(s: string): boolean {
|
|
25
|
+
return /^0x[0-9a-fA-F]{40}$/.test(s);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function main() {
|
|
29
|
+
const privateKey = process.env.PRIVATE_KEY;
|
|
30
|
+
if (!privateKey) {
|
|
31
|
+
console.error('Set PRIVATE_KEY');
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
const pk = privateKey.startsWith('0x') ? (privateKey as `0x${string}`) : (`0x${privateKey}` as `0x${string}`);
|
|
35
|
+
const account = privateKeyToAccount(pk);
|
|
36
|
+
|
|
37
|
+
const toAddress = process.argv[2];
|
|
38
|
+
const amountWeiRaw = process.argv[3];
|
|
39
|
+
const tokenAddress = process.argv[4]; // optional: BNB if omitted or "BNB" or 0x0
|
|
40
|
+
|
|
41
|
+
if (!toAddress || !amountWeiRaw) {
|
|
42
|
+
console.error('Usage: send-token.ts <toAddress> <amountWei> [tokenAddress]');
|
|
43
|
+
console.error(' toAddress: recipient 0x... address');
|
|
44
|
+
console.error(' amountWei: amount in wei (for BNB or token smallest unit)');
|
|
45
|
+
console.error(' tokenAddress: optional; omit or BNB/0x0 = native BNB; else ERC20 contract address');
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
if (!isAddress(toAddress)) {
|
|
49
|
+
console.error('Invalid toAddress:', toAddress);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const amountWei = BigInt(amountWeiRaw);
|
|
54
|
+
if (amountWei <= 0n) {
|
|
55
|
+
console.error('amountWei must be positive');
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const isNative =
|
|
60
|
+
!tokenAddress ||
|
|
61
|
+
tokenAddress.toUpperCase() === 'BNB' ||
|
|
62
|
+
tokenAddress === ZERO ||
|
|
63
|
+
tokenAddress.toLowerCase() === '0x0000000000000000000000000000000000000000';
|
|
64
|
+
|
|
65
|
+
const rpcUrl = process.env.BSC_RPC_URL || 'https://bsc-dataseed.binance.org';
|
|
66
|
+
const client = createWalletClient({
|
|
67
|
+
account,
|
|
68
|
+
chain: bsc,
|
|
69
|
+
transport: http(rpcUrl),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
let txHash: `0x${string}`;
|
|
73
|
+
|
|
74
|
+
if (isNative) {
|
|
75
|
+
txHash = await client.sendTransaction({
|
|
76
|
+
to: toAddress as `0x${string}`,
|
|
77
|
+
value: amountWei,
|
|
78
|
+
});
|
|
79
|
+
} else {
|
|
80
|
+
if (!isAddress(tokenAddress)) {
|
|
81
|
+
console.error('Invalid tokenAddress:', tokenAddress);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
txHash = await client.writeContract({
|
|
85
|
+
address: tokenAddress as `0x${string}`,
|
|
86
|
+
abi: ERC20_ABI,
|
|
87
|
+
functionName: 'transfer',
|
|
88
|
+
args: [toAddress as `0x${string}`, amountWei],
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
console.log(JSON.stringify({ txHash, to: toAddress, amountWei: amountWei.toString(), native: isNative }, null, 2));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
main().catch((e) => {
|
|
96
|
+
console.error(e.message || e);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Four.meme - token detail + trading info (REST API)
|
|
4
|
+
* GET /meme-api/v1/private/token/get/v2?address=<address>
|
|
5
|
+
* Usage: npx tsx token-get.ts <tokenAddress>
|
|
6
|
+
* Output: JSON token info and trading info.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const API_BASE = 'https://four.meme/meme-api/v1';
|
|
10
|
+
|
|
11
|
+
async function main() {
|
|
12
|
+
const address = process.argv[2];
|
|
13
|
+
if (!address) {
|
|
14
|
+
console.error('Usage: npx tsx token-get.ts <tokenAddress>');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const url = `${API_BASE}/private/token/get/v2?address=${encodeURIComponent(address)}`;
|
|
18
|
+
const res = await fetch(url, {
|
|
19
|
+
headers: { Accept: 'application/json' },
|
|
20
|
+
});
|
|
21
|
+
if (!res.ok) {
|
|
22
|
+
throw new Error(`token/get/v2 failed: ${res.status} ${await res.text()}`);
|
|
23
|
+
}
|
|
24
|
+
const data = await res.json();
|
|
25
|
+
console.log(JSON.stringify(data, null, 2));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
main().catch((e) => {
|
|
29
|
+
console.error(e.message || e);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
});
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Four.meme - token list (REST API)
|
|
4
|
+
* POST /meme-api/v1/public/token/search
|
|
5
|
+
*
|
|
6
|
+
* Legacy (still supported): [--orderBy=Hot] [--tokenName=] [--listedPancake=false] ...
|
|
7
|
+
* New params: [--type=HOT] [--listType=NOR] [--keyword=] [--tag=a,b] [--status=PUBLISH|TRADE|ALL] [--sort=DESC|ASC] [--version=V9]
|
|
8
|
+
* Legacy shortcut: [--queryMode=Binance|USD1] (infers listType BIN/BIN_DEX or USD1/USD1_DEX using listedPancake)
|
|
9
|
+
*
|
|
10
|
+
* Usage: npx tsx token-list.ts [options]
|
|
11
|
+
* Output: JSON list of tokens.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const API_BASE = 'https://four.meme/meme-api/v1';
|
|
15
|
+
|
|
16
|
+
function parseArg(name: string, defaultValue: string): string {
|
|
17
|
+
const prefix = `--${name}=`;
|
|
18
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
19
|
+
const arg = process.argv[i];
|
|
20
|
+
if (arg.startsWith(prefix)) return arg.slice(prefix.length);
|
|
21
|
+
}
|
|
22
|
+
return defaultValue;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function hasArg(name: string): boolean {
|
|
26
|
+
const prefix = `--${name}=`;
|
|
27
|
+
return process.argv.some((a) => a.startsWith(prefix));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Map legacy orderBy → public search `type` (sort controlled by --sort=; default DESC). */
|
|
31
|
+
function typeFromLegacyOrderBy(orderBy: string): string {
|
|
32
|
+
const k = orderBy.replace(/\s/g, '').toLowerCase();
|
|
33
|
+
const map: Record<string, string> = {
|
|
34
|
+
hot: 'HOT',
|
|
35
|
+
time: 'NEW',
|
|
36
|
+
timedesc: 'NEW',
|
|
37
|
+
new: 'NEW',
|
|
38
|
+
progress: 'PROGRESS',
|
|
39
|
+
progressdesc: 'PROGRESS',
|
|
40
|
+
trading: 'VOL',
|
|
41
|
+
tradingdesc: 'VOL',
|
|
42
|
+
vol: 'VOL',
|
|
43
|
+
volume: 'VOL',
|
|
44
|
+
last: 'LAST',
|
|
45
|
+
cap: 'CAP',
|
|
46
|
+
dex: 'DEX',
|
|
47
|
+
graduated: 'DEX',
|
|
48
|
+
burn: 'BURN',
|
|
49
|
+
};
|
|
50
|
+
return map[k] ?? 'HOT';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function main() {
|
|
54
|
+
const pageIndex = Math.max(1, parseInt(parseArg('pageIndex', '1'), 10) || 1);
|
|
55
|
+
const pageSize = Math.min(100, Math.max(1, parseInt(parseArg('pageSize', '30'), 10) || 30));
|
|
56
|
+
const sort = (parseArg('sort', 'DESC').toUpperCase() === 'ASC' ? 'ASC' : 'DESC') as 'ASC' | 'DESC';
|
|
57
|
+
|
|
58
|
+
const listedPancake = parseArg('listedPancake', 'false').toLowerCase() === 'true';
|
|
59
|
+
|
|
60
|
+
// New API listType: allow explicit listType, or infer from legacy queryMode + listedPancake.
|
|
61
|
+
const explicitListType = hasArg('listType') ? parseArg('listType', 'NOR') : '';
|
|
62
|
+
const queryMode = parseArg('queryMode', '').trim().toLowerCase();
|
|
63
|
+
const inferredListType = (() => {
|
|
64
|
+
if (!queryMode) return '';
|
|
65
|
+
if (queryMode === 'binance' || queryMode === 'bnb' || queryMode === 'bnb_mpc') {
|
|
66
|
+
return listedPancake ? 'BIN_DEX' : 'BIN';
|
|
67
|
+
}
|
|
68
|
+
if (queryMode === 'usd1') {
|
|
69
|
+
return listedPancake ? 'USD1_DEX' : 'USD1';
|
|
70
|
+
}
|
|
71
|
+
return '';
|
|
72
|
+
})();
|
|
73
|
+
const listType = explicitListType || inferredListType || parseArg('listType', 'NOR');
|
|
74
|
+
const type = hasArg('type')
|
|
75
|
+
? parseArg('type', 'HOT')
|
|
76
|
+
: typeFromLegacyOrderBy(parseArg('orderBy', 'Hot'));
|
|
77
|
+
|
|
78
|
+
let status: string;
|
|
79
|
+
if (hasArg('status')) {
|
|
80
|
+
status = parseArg('status', 'ALL').toUpperCase();
|
|
81
|
+
} else {
|
|
82
|
+
status = listedPancake ? 'TRADE' : 'PUBLISH';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const keywordRaw = hasArg('keyword') ? parseArg('keyword', '') : parseArg('tokenName', '');
|
|
86
|
+
const labelsRaw = hasArg('tag') ? parseArg('tag', '') : parseArg('labels', '');
|
|
87
|
+
const symbol = parseArg('symbol', '').trim();
|
|
88
|
+
|
|
89
|
+
const body: Record<string, unknown> = {
|
|
90
|
+
type,
|
|
91
|
+
listType,
|
|
92
|
+
pageIndex,
|
|
93
|
+
pageSize,
|
|
94
|
+
status,
|
|
95
|
+
sort,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
if (keywordRaw.trim() !== '') {
|
|
99
|
+
body.keyword = keywordRaw.trim();
|
|
100
|
+
}
|
|
101
|
+
if (symbol !== '') {
|
|
102
|
+
body.symbol = symbol;
|
|
103
|
+
}
|
|
104
|
+
if (labelsRaw.trim() !== '') {
|
|
105
|
+
body.tag = labelsRaw
|
|
106
|
+
.split(',')
|
|
107
|
+
.map((t) => t.trim())
|
|
108
|
+
.filter(Boolean);
|
|
109
|
+
}
|
|
110
|
+
const version = parseArg('version', '').trim();
|
|
111
|
+
if (version !== '') {
|
|
112
|
+
body.version = version;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const url = `${API_BASE}/public/token/search`;
|
|
116
|
+
const res = await fetch(url, {
|
|
117
|
+
method: 'POST',
|
|
118
|
+
headers: {
|
|
119
|
+
Accept: 'application/json',
|
|
120
|
+
'Content-Type': 'application/json',
|
|
121
|
+
},
|
|
122
|
+
body: JSON.stringify(body),
|
|
123
|
+
});
|
|
124
|
+
if (!res.ok) {
|
|
125
|
+
throw new Error(`token/search failed: ${res.status} ${await res.text()}`);
|
|
126
|
+
}
|
|
127
|
+
const data = await res.json();
|
|
128
|
+
console.log(JSON.stringify(data, null, 2));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
main().catch((e) => {
|
|
132
|
+
console.error(e.message || e);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
});
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Four.meme - token rankings (REST API)
|
|
4
|
+
* POST /meme-api/v1/public/token/ranking
|
|
5
|
+
*
|
|
6
|
+
* Backward compatible: <orderBy> where orderBy = Time | ProgressDesc | TradingDesc | Hot | Graduated
|
|
7
|
+
* [--barType=HOUR24|HOUR4|HOUR1|MIN30|MIN5] (only for TradingDesc; maps to VOL_* windows)
|
|
8
|
+
*
|
|
9
|
+
* You may also pass a native API RankingType directly: NEW, PROGRESS, VOL_DAY_1, HOT, DEX, VOL, LAST, CAP, …
|
|
10
|
+
*
|
|
11
|
+
* Optional filters: [--pageSize=20] [--symbol=] [--version=] [--rankingKind=]
|
|
12
|
+
* [--minCap=] [--maxCap=] [--minVol=] [--maxVol=] [--minHold=] [--maxHold=]
|
|
13
|
+
*
|
|
14
|
+
* Usage: npx tsx token-rankings.ts <orderOrType> [--barType=HOUR24] [filters...]
|
|
15
|
+
* Output: JSON ranking list.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const API_BASE = 'https://four.meme/meme-api/v1';
|
|
19
|
+
|
|
20
|
+
const LEGACY_ORDER_BY = ['Time', 'ProgressDesc', 'TradingDesc', 'Hot', 'Graduated'] as const;
|
|
21
|
+
|
|
22
|
+
/** Legacy TradingDesc + barType → public ranking `type`. */
|
|
23
|
+
const BAR_TYPE_TO_VOL_TYPE: Record<string, string> = {
|
|
24
|
+
HOUR24: 'VOL_DAY_1',
|
|
25
|
+
DAY1: 'VOL_DAY_1',
|
|
26
|
+
HOUR4: 'VOL_HOUR_4',
|
|
27
|
+
HOUR1: 'VOL_HOUR_1',
|
|
28
|
+
MIN30: 'VOL_MIN_30',
|
|
29
|
+
MIN5: 'VOL_MIN_5',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const LEGACY_TO_TYPE: Record<string, string> = {
|
|
33
|
+
Time: 'NEW',
|
|
34
|
+
ProgressDesc: 'PROGRESS',
|
|
35
|
+
TradingDesc: 'VOL_DAY_1',
|
|
36
|
+
Hot: 'HOT',
|
|
37
|
+
Graduated: 'DEX',
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/** Native ranking types allowed as the first argument (aligned with API RankingType). */
|
|
41
|
+
const NATIVE_RANKING_TYPES = new Set([
|
|
42
|
+
'NEW',
|
|
43
|
+
'PROGRESS',
|
|
44
|
+
'VOL_MIN_5',
|
|
45
|
+
'VOL_MIN_30',
|
|
46
|
+
'VOL_HOUR_1',
|
|
47
|
+
'VOL_HOUR_4',
|
|
48
|
+
'VOL_DAY_1',
|
|
49
|
+
'VOL',
|
|
50
|
+
'LAST',
|
|
51
|
+
'HOT',
|
|
52
|
+
'CAP',
|
|
53
|
+
'DEX',
|
|
54
|
+
'BURN',
|
|
55
|
+
]);
|
|
56
|
+
|
|
57
|
+
function parseArg(name: string): string | undefined {
|
|
58
|
+
const prefix = `--${name}=`;
|
|
59
|
+
for (let i = 3; i < process.argv.length; i++) {
|
|
60
|
+
const arg = process.argv[i];
|
|
61
|
+
if (arg.startsWith(prefix)) return arg.slice(prefix.length);
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function parseNumArg(name: string): number | undefined {
|
|
67
|
+
const v = parseArg(name);
|
|
68
|
+
if (v == null || v.trim() === '') return undefined;
|
|
69
|
+
const n = Number(v);
|
|
70
|
+
return Number.isFinite(n) ? n : undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function resolveRankingType(first: string, barType?: string): string {
|
|
74
|
+
if (first === 'TradingDesc') {
|
|
75
|
+
if (barType && BAR_TYPE_TO_VOL_TYPE[barType]) {
|
|
76
|
+
return BAR_TYPE_TO_VOL_TYPE[barType];
|
|
77
|
+
}
|
|
78
|
+
return 'VOL_DAY_1';
|
|
79
|
+
}
|
|
80
|
+
if (LEGACY_TO_TYPE[first]) {
|
|
81
|
+
return LEGACY_TO_TYPE[first];
|
|
82
|
+
}
|
|
83
|
+
return first;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function normalizeLegacyOrderBy(s: string): string {
|
|
87
|
+
const map: Record<string, string> = {
|
|
88
|
+
time: 'Time',
|
|
89
|
+
progressdesc: 'ProgressDesc',
|
|
90
|
+
tradingdesc: 'TradingDesc',
|
|
91
|
+
hot: 'Hot',
|
|
92
|
+
graduated: 'Graduated',
|
|
93
|
+
};
|
|
94
|
+
return map[s.toLowerCase()] ?? s;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function main() {
|
|
98
|
+
const rawFirst = process.argv[2];
|
|
99
|
+
const first = rawFirst ? normalizeLegacyOrderBy(rawFirst) : '';
|
|
100
|
+
if (!first) {
|
|
101
|
+
console.error(
|
|
102
|
+
'Usage: npx tsx token-rankings.ts <orderBy|RankingType> [--barType=HOUR24] [--pageSize=20] ...',
|
|
103
|
+
);
|
|
104
|
+
console.error(
|
|
105
|
+
'Legacy orderBy: Time | ProgressDesc | TradingDesc | Hot | Graduated (barType for TradingDesc)',
|
|
106
|
+
);
|
|
107
|
+
console.error('Or native type: NEW, PROGRESS, VOL_DAY_1, HOT, DEX, VOL, LAST, CAP, BURN, ...');
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const barType = parseArg('barType');
|
|
112
|
+
let rankingType = resolveRankingType(first, barType);
|
|
113
|
+
|
|
114
|
+
const isLegacy = (LEGACY_ORDER_BY as readonly string[]).includes(first);
|
|
115
|
+
if (!isLegacy && !NATIVE_RANKING_TYPES.has(rankingType)) {
|
|
116
|
+
console.error(`Unknown ranking type: ${first}`);
|
|
117
|
+
console.error(
|
|
118
|
+
`Use legacy: ${LEGACY_ORDER_BY.join(' | ')} or native: ${[...NATIVE_RANKING_TYPES].join(', ')}`,
|
|
119
|
+
);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const pageSizeArg = parseNumArg('pageSize');
|
|
124
|
+
const pageSize = pageSizeArg != null ? Math.min(100, Math.max(1, pageSizeArg)) : 20;
|
|
125
|
+
|
|
126
|
+
const body: Record<string, unknown> = {
|
|
127
|
+
type: rankingType,
|
|
128
|
+
pageSize,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const symbol = parseArg('symbol')?.trim();
|
|
132
|
+
if (symbol) body.symbol = symbol;
|
|
133
|
+
const version = parseArg('version')?.trim();
|
|
134
|
+
if (version) body.version = version;
|
|
135
|
+
const rankingKind = parseArg('rankingKind')?.trim();
|
|
136
|
+
if (rankingKind) body.rankingKind = rankingKind;
|
|
137
|
+
|
|
138
|
+
for (const key of ['minCap', 'maxCap', 'minVol', 'maxVol', 'minHold', 'maxHold'] as const) {
|
|
139
|
+
const n = parseNumArg(key);
|
|
140
|
+
if (n !== undefined) body[key] = n;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const url = `${API_BASE}/public/token/ranking`;
|
|
144
|
+
const res = await fetch(url, {
|
|
145
|
+
method: 'POST',
|
|
146
|
+
headers: {
|
|
147
|
+
Accept: 'application/json',
|
|
148
|
+
'Content-Type': 'application/json',
|
|
149
|
+
},
|
|
150
|
+
body: JSON.stringify(body),
|
|
151
|
+
});
|
|
152
|
+
if (!res.ok) {
|
|
153
|
+
throw new Error(`token/ranking failed: ${res.status} ${await res.text()}`);
|
|
154
|
+
}
|
|
155
|
+
const data = await res.json();
|
|
156
|
+
console.log(JSON.stringify(data, null, 2));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
main().catch((e) => {
|
|
160
|
+
console.error(e.message || e);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Verification helper: fetch TokenManager2 events for the last N blocks on BSC.
|
|
4
|
+
* Usage: npx tsx verify-events.ts [blockCount]
|
|
5
|
+
* Default blockCount 50. No private key or tx, read-only.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createPublicClient, http, parseAbiItem } from 'viem';
|
|
9
|
+
import { bsc } from 'viem/chains';
|
|
10
|
+
|
|
11
|
+
const TOKEN_MANAGER2_BSC = '0x5c952063c7fc8610FFDB798152D69F0B9550762b' as const;
|
|
12
|
+
const EVENTS = [
|
|
13
|
+
parseAbiItem(
|
|
14
|
+
'event TokenCreate(address creator, address token, uint256 requestId, string name, string symbol, uint256 totalSupply, uint256 launchTime, uint256 launchFee)'
|
|
15
|
+
),
|
|
16
|
+
parseAbiItem(
|
|
17
|
+
'event TokenPurchase(address token, address account, uint256 price, uint256 amount, uint256 cost, uint256 fee, uint256 offers, uint256 funds)'
|
|
18
|
+
),
|
|
19
|
+
parseAbiItem(
|
|
20
|
+
'event TokenSale(address token, address account, uint256 price, uint256 amount, uint256 cost, uint256 fee, uint256 offers, uint256 funds)'
|
|
21
|
+
),
|
|
22
|
+
parseAbiItem('event LiquidityAdded(address base, uint256 offers, address quote, uint256 funds)'),
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
async function main() {
|
|
26
|
+
const blockCount = parseInt(process.argv[2] ?? '50', 10) || 50;
|
|
27
|
+
const rpcUrl = process.env.BSC_RPC_URL || 'https://bsc-dataseed.binance.org';
|
|
28
|
+
const client = createPublicClient({
|
|
29
|
+
chain: bsc,
|
|
30
|
+
transport: http(rpcUrl),
|
|
31
|
+
});
|
|
32
|
+
const block = await client.getBlockNumber();
|
|
33
|
+
const fromBlock = block - BigInt(blockCount);
|
|
34
|
+
const toBlock = block;
|
|
35
|
+
const logs = await client.getLogs({
|
|
36
|
+
address: TOKEN_MANAGER2_BSC,
|
|
37
|
+
events: EVENTS,
|
|
38
|
+
fromBlock: fromBlock < 0n ? 0n : fromBlock,
|
|
39
|
+
toBlock,
|
|
40
|
+
});
|
|
41
|
+
console.log(JSON.stringify({ fromBlock: String(fromBlock), toBlock: String(toBlock), count: logs.length, events: logs.map((l) => ({ eventName: l.eventName, blockNumber: Number(l.blockNumber), args: l.args })) }, null, 2));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
main().catch((e) => {
|
|
45
|
+
console.error(e.message || e);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
});
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: contract-profiler
|
|
3
|
+
description: |
|
|
4
|
+
合约画像分析器。判定合约类型、识别权限角色、提取特权函数清单。
|
|
5
|
+
作为 audit-plus 的前置分析器,为深度审计提供结构化的合约画像。
|
|
6
|
+
触发词:合约类型、这是什么合约、合约权限、privileged functions
|
|
7
|
+
metadata:
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
type: analysis
|
|
10
|
+
group: skillpp
|
|
11
|
+
dependsOn:
|
|
12
|
+
- query-token-info
|
|
13
|
+
- audit-plus
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Contract Profiler — 合约画像
|
|
17
|
+
|
|
18
|
+
> **给 AI 的指引**:收到合约源码后,按以下维度逐项分析,输出结构化 JSON。
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## EXECUTE FLOW
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
STEP 0: 获取源码
|
|
26
|
+
IF 有合约地址 AND 已验证 → curl 区块浏览器 API 拉源码
|
|
27
|
+
ELSE → 用户提供源码
|
|
28
|
+
→ 进入 STEP 1
|
|
29
|
+
|
|
30
|
+
STEP 1: 分类合约类型
|
|
31
|
+
按 Type Classification 表逐项判定
|
|
32
|
+
|
|
33
|
+
STEP 2: 识别权限角色
|
|
34
|
+
搜索 owner/admin/governor/guardian/operator 关键词
|
|
35
|
+
搜索 onlyOwner/onlyRole/onlyGovernor 修饰符
|
|
36
|
+
|
|
37
|
+
STEP 3: 枚举特权函数
|
|
38
|
+
列出所有带权限修饰符的函数 + 每个函数的权限级别
|
|
39
|
+
|
|
40
|
+
STEP 4: 输出画像 JSON
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Type Classification
|
|
46
|
+
|
|
47
|
+
| 特征 | 类型 | 判定规则 |
|
|
48
|
+
|------|------|---------|
|
|
49
|
+
| `import` ERC20 / `IERC20` | TOKEN | 实现了 transfer/balanceOf |
|
|
50
|
+
| `import` ERC721 / `IERC721` | NFT | 实现了 ownerOf/tokenURI |
|
|
51
|
+
| 含 `mint()` + `burn()` + 税率变量 | TAX_TOKEN | Meme/反射代币 |
|
|
52
|
+
| 含 `swap()` / `addLiquidity()` | DEX_PAIR | 流动性对 |
|
|
53
|
+
| 含 `stake()` / `unstake()` / `reward` | STAKING | 质押合约 |
|
|
54
|
+
| 含 `deposit()` / `withdraw()` / `strategy` | VAULT | 金库/机枪池 |
|
|
55
|
+
| `import` Proxy / UUPS / Transparent | PROXY | 可升级代理 |
|
|
56
|
+
| `import` GnosisSafe / MultiSig | MULTISIG | 多签钱包 |
|
|
57
|
+
| 含 `createToken` / `launch` | LAUNCHPAD | 发射台 |
|
|
58
|
+
| 仅 `receive()` + 分红逻辑 | DIVIDEND | 分红合约 |
|
|
59
|
+
| 以上都不匹配 | UNKNOWN | 自定义逻辑 |
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Permission Role Mapping
|
|
64
|
+
|
|
65
|
+
| 角色名 | 常见关键词 | 风险权重 |
|
|
66
|
+
|--------|-----------|---------|
|
|
67
|
+
| owner | `owner`, `_owner`, `onlyOwner` | x1.0 |
|
|
68
|
+
| admin | `admin`, `DEFAULT_ADMIN_ROLE` | x1.0 |
|
|
69
|
+
| guardian | `guardian`, `_guardian`, `onlyGuardian` | x0.8 |
|
|
70
|
+
| operator | `operator`, `onlyOperator` | x0.9 |
|
|
71
|
+
| minter | `minter`, `MINTER_ROLE` | x1.2 |
|
|
72
|
+
| pauser | `pauser`, `PAUSER_ROLE` | x1.1 |
|
|
73
|
+
| feeManager | `feeManager`, `setFee`, `setTax` | x1.3 |
|
|
74
|
+
| upgrader | `upgrader`, `UPGRADER_ROLE` | x1.5 |
|
|
75
|
+
| blacklister | `blacklister`, `BLACKLISTER_ROLE` | x1.4 |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Privileged Function Severity
|
|
80
|
+
|
|
81
|
+
| 函数类别 | 示例 | 风险等级 |
|
|
82
|
+
|---------|------|---------|
|
|
83
|
+
| 资金提取 | `withdraw()`, `rescueETH()`, `rescueToken()` | CRITICAL |
|
|
84
|
+
| 无限增发 | `mint()` 无上限/无onlyOwner | CRITICAL |
|
|
85
|
+
| 代理升级 | `upgradeTo()`, `setImplementation()` | CRITICAL |
|
|
86
|
+
| 用户冻结 | `blacklist()`, `pause()`, `disableTransfer()` | HIGH |
|
|
87
|
+
| 费率修改 | `setFee()`, `setTax()`, `setMaxTxAmount()` | HIGH |
|
|
88
|
+
| 权限转移 | `transferOwnership()`, `grantRole()` | MEDIUM |
|
|
89
|
+
| 参数调整 | `setMinAmount()`, `setCooldown()` | MEDIUM |
|
|
90
|
+
| 元数据修改 | `setName()`, `setSymbol()` | LOW |
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Output Schema
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"contractProfile": {
|
|
99
|
+
"name": "CHIP",
|
|
100
|
+
"type": "DIVIDEND",
|
|
101
|
+
"subType": "BurnToEarn",
|
|
102
|
+
"compiler": "0.8.35",
|
|
103
|
+
"isProxy": false,
|
|
104
|
+
"isVerified": true,
|
|
105
|
+
"roles": [
|
|
106
|
+
{ "name": "owner", "address": "0x4A80...cDf", "type": "EOA", "riskWeight": 1.0 }
|
|
107
|
+
],
|
|
108
|
+
"privilegedFunctions": [
|
|
109
|
+
{ "name": "rescueETH", "role": "owner", "severity": "CRITICAL", "description": "可提取合约内全部ETH" },
|
|
110
|
+
{ "name": "setMinBuyAmount", "role": "owner", "severity": "MEDIUM", "description": "修改最小购买金额" }
|
|
111
|
+
],
|
|
112
|
+
"inheritanceChain": ["CHIP"],
|
|
113
|
+
"usesStandardLibs": ["OpenZeppelin:ReentrancyGuard"],
|
|
114
|
+
"permissionSummary": "单owner EOA控制,无多签/时间锁",
|
|
115
|
+
"riskIndicators": ["owner_can_drain_eth", "single_eoa_control", "no_timelock"]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|