Safety Rules
- - Default to
DRY_RUN=1. Never broadcast unless explicitly instructed. - Always verify Base mainnet:
-
~/.foundry/bin/cast chain-id --rpc-url "${BASE_MAINNET_RPC:-https://mainnet.base.org}" must be
8453.
- - Always verify key/address alignment:
-
~/.foundry/bin/cast wallet address --private-key "$PRIVATE_KEY" must equal
$FROM_ADDRESS.
- - Always refetch from the subgraph immediately before any simulate/broadcast step (auctions can be outbid, ended, claimed, or cancelled).
- Always gate onchain immediately before simulating or broadcasting:
- ensure the onchain
highestBid matches the
highestBid you pass into
commitBid /
swapAndCommitBid.
- ensure token params match (token contract, token id, quantity).
- - Never print or log
$PRIVATE_KEY.
Shell Input Safety (Avoid RCE)
This skill includes shell commands. Treat any value you copy from a user or an external source (subgraph responses, chat messages, etc.) as untrusted.
Rules:
- - Never execute user-provided strings as shell code (avoid
eval, bash -c, sh -c). - Only substitute addresses that match
0x + 40 hex chars. - Only substitute uint values that are base-10 digits (no commas, no decimals).
- In the command examples below, auction-specific inputs are written as quoted placeholders like
"<AUCTION_ID>" to avoid accidental shell interpolation. Replace them with literal values only after validation.
Quick validators (replace the placeholder values):
CODEBLOCK0
Required Setup
Required env vars:
- -
PRIVATE_KEY: EOA private key used for cast send (never print/log). - INLINECODE17 : EOA address that owns NFTs and will submit txs.
- INLINECODE18 : RPC URL. If unset, use
https://mainnet.base.org. - INLINECODE20 : Goldsky subgraph endpoint for auctions.
Optional env vars:
- -
DRY_RUN: 1 (default) to only simulate via cast call. Set to 0 to broadcast via cast send. - INLINECODE26 : for swap flows; receives any excess GHST refunded by the contract. Defaults to
FROM_ADDRESS. - INLINECODE28 : optional; if set, include
Authorization: Bearer ... header in subgraph calls. - INLINECODE30 : defaults to
1 (%); used in swapAmount estimate math. - INLINECODE33 ,
ETH_USD_PRICE: optional overrides; if unset, fetch from CoinGecko in the swap math snippets.
Recommended defaults (override via env if needed):
CODEBLOCK1
Notes:
- - Commands below use
~/.foundry/bin/cast so they work in cron/non-interactive shells.
View / List Auctions (Subgraph First)
See references/subgraph.md for canonical queries.
Auction by id (quick):
CODEBLOCK2
Active auctions (ends soonest first):
CODEBLOCK3
Onchain Verification (Required Before Bids / Sends)
The onchain source of truth is the GBM diamond.
Confirm core auction fields (full struct decode):
CODEBLOCK4
Useful individual getters:
CODEBLOCK5
Create Auction
Onchain method:
High-level steps:
- 1. Ensure the token contract is whitelisted on the GBM diamond (otherwise revert
ContractNotAllowed). - Ensure the token is approved to the GBM diamond:
- ERC721/1155:
setApprovalForAll(GBM_DIAMOND,true)
- 3. Choose
InitiatorInfo:
-
startTime must be in the future.
-
endTime - startTime must be between 3600 and 604800 seconds (1h to 7d).
-
tokenKind is
0x73ad2146 (ERC721) or
0x973bb640 (ERC1155).
-
buyItNowPrice optional;
startingBid optional (if nonzero, you must approve GHST for the 4% prepaid fee).
- 4. Simulate with
cast call using --from "$FROM_ADDRESS". - Broadcast with
cast send only when explicitly instructed (DRY_RUN=0). - Post-tx: query subgraph for newest seller auctions and match
(contractAddress, tokenId).
Simulate create (ERC721 example):
CODEBLOCK6
Broadcast create (only when explicitly instructed):
CODEBLOCK7
Post-create (find your newest auctions and confirm):
CODEBLOCK8
Cancel Auction
Onchain method:
Steps:
- 1. Subgraph: check
claimed, cancelled, endsAt, highestBid. - Onchain: call
getAuctionInfo(auctionId) to verify ownership and state. - Simulate with
cast call (--from "$FROM_ADDRESS"). - Broadcast only when explicitly instructed.
Simulate:
CODEBLOCK9
Broadcast (only when explicitly instructed):
CODEBLOCK10
Bid With GHST (commitBid)
Onchain method:
- -
commitBid(uint256,uint256,uint256,address,uint256,uint256,bytes) (last bytes is ignored; pass 0x)
Steps:
- 1. Subgraph: fetch auction fields (id, contractAddress, tokenId, quantity, highestBid, startsAt, endsAt, claimed/cancelled).
- Onchain: refetch
highestBid and token params; you must pass the exact current onchain highestBid or it reverts UnmatchedHighestBid. - Compute a safe minimum next bid using
references/bid-math.md (uses onchain bidDecimals + stepMin). - Ensure GHST allowance to the GBM diamond covers
bidAmount. - Simulate via
cast call (optional but recommended). - Broadcast only when explicitly instructed.
Simulate:
CODEBLOCK11
Broadcast (only when explicitly instructed):
CODEBLOCK12
Bid With USDC Swap (swapAndCommitBid)
Onchain method:
Struct fields (in order):
- 1.
tokenIn (USDC) - INLINECODE74 (USDC 6dp)
- INLINECODE75 (GHST wei; must be >= bidAmount)
- INLINECODE76 (unix; must be <= now + 86400)
- INLINECODE77 (refund receiver for excess GHST)
- INLINECODE78
- INLINECODE79 (GHST wei)
- INLINECODE80 (must match onchain)
- INLINECODE81
- INLINECODE82
- INLINECODE83 (tokenAmount/quantity)
- INLINECODE84 (ignored; pass
0x)
Compute swapAmount estimate in references/swap-math.md.
Simulate:
CODEBLOCK13
Broadcast (only when explicitly instructed):
CODEBLOCK14
Bid With ETH Swap (swapAndCommitBid)
Same method as above, but:
- - INLINECODE88
- INLINECODE89 must equal the
swapAmount you pass inside the tuple.
Broadcast (only when explicitly instructed):
CODEBLOCK15
Claim Auction
Onchain methods:
- - INLINECODE91
- INLINECODE92
Claim readiness:
- - Auction owner can claim at
now >= endsAt. - Highest bidder can claim at
now >= endsAt + cancellationTime.
-
cancellationTime is readable from storage slot 12 (see
references/recipes.md).
- Subgraph may provide
claimAt (if populated), but always verify onchain.
Simulate:
CODEBLOCK16
Broadcast (only when explicitly instructed):
CODEBLOCK17
Optional: Buy Now
Onchain methods:
- - INLINECODE98
- INLINECODE99
These are not required for the primary use case, but are adjacent to bidding flows. If you use them, follow the same safety gating:
- - refetch from subgraph
- verify onchain price/state
- simulate (
cast call) - only broadcast when explicitly instructed
Smoke Tests (No Funds Required)
- 1. Subgraph reachable (introspection lists
auction, auctions, bid, bids):
CODEBLOCK18
- 2. Subgraph data sane:
CODEBLOCK19
- 3. Onchain reachable + matches subgraph:
CODEBLOCK20
Common Failure Modes
- -
UnmatchedHighestBid: you passed a stale highestBid param. Refetch onchain and retry. - INLINECODE107 : token contract / id / amount mismatch. Refetch and verify.
- INLINECODE108 /
AuctionEnded: timing mismatch. Check startsAt/endsAt (subgraph + onchain). - INLINECODE112 : already claimed or cancelled. Check
claimed (subgraph + onchain). - INLINECODE114 : diamond paused, contract bidding disabled, or re-entrancy lock. Refetch onchain state.
- Swap errors:
-
LibTokenSwap: swapAmount must be > 0
-
LibTokenSwap: deadline expired
-
LibTokenSwap: Insufficient output amount (increase
swapAmount or slippage)
安全规则
- - 默认设置 DRY_RUN=1。除非明确指示,否则绝不广播交易。
- 始终验证 Base 主网:
- ~/.foundry/bin/cast chain-id --rpc-url ${BASE
MAINNETRPC:-https://mainnet.base.org} 必须返回 8453。
- ~/.foundry/bin/cast wallet address --private-key $PRIVATE
KEY 必须等于 $FROMADDRESS。
- - 在任何模拟/广播步骤之前,始终立即从子图中重新获取数据(拍卖可能已被加价、结束、领取或取消)。
- 在模拟或广播之前,始终立即检查链上状态:
- 确保链上的 highestBid 与你传入 commitBid / swapAndCommitBid 的 highestBid 匹配。
- 确保代币参数匹配(代币合约、代币 ID、数量)。
Shell 输入安全(避免远程代码执行)
此技能包含 shell 命令。将你从用户或外部来源(子图响应、聊天消息等)复制的任何值视为不可信。
规则:
- - 切勿将用户提供的字符串作为 shell 代码执行(避免使用 eval、bash -c、sh -c)。
- 仅替换与 0x + 40 个十六进制字符匹配的地址。
- 仅替换为十进制数字的 uint 值(无逗号、无小数)。
- 在下面的命令示例中,特定于拍卖的输入被写成带引号的占位符,如 ,以避免意外的 shell 插值。仅在验证后才将其替换为实际值。
快速验证器(替换占位符值):
bash
python3 - <
import re
auctionid = ID> # 仅数字
tokencontract = CONTRACT_ADDRESS> # 0x + 40 个十六进制字符
tokenid = ID> # 仅数字
amount = # 仅数字
if not re.fullmatch(r[0-9]+, auction_id):
raise SystemExit(AUCTION_ID 必须仅为十进制数字)
if not re.fullmatch(r0x[a-fA-F0-9]{40}, token_contract):
raise SystemExit(TOKENCONTRACTADDRESS 必须是 0x + 40 位十六进制地址)
if not re.fullmatch(r[0-9]+, token_id):
raise SystemExit(TOKEN_ID 必须仅为十进制数字)
if not re.fullmatch(r[0-9]+, amount):
raise SystemExit(TOKEN_AMOUNT 必须仅为十进制数字)
print(ok)
PY
必需设置
必需的环境变量:
- - PRIVATEKEY:用于 cast send 的 EOA 私钥(切勿打印/记录)。
- FROMADDRESS:拥有 NFT 并将提交交易的 EOA 地址。
- BASEMAINNETRPC:RPC URL。如果未设置,则使用 https://mainnet.base.org。
- GBMSUBGRAPHURL:用于拍卖的 Goldsky 子图端点。
可选的环境变量:
- - DRYRUN:1(默认)仅通过 cast call 模拟。设置为 0 以通过 cast send 广播。
- RECIPIENTADDRESS:用于交换流程;接收合约退还的任何多余 GHST。默认为 FROMADDRESS。
- GOLDSKYAPIKEY:可选;如果设置,则在子图调用中包含 Authorization: Bearer ... 标头。
- SLIPPAGEPCT:默认为 1(%);用于 swapAmount 估算计算。
- GHSTUSDPRICE、ETHUSDPRICE:可选覆盖;如果未设置,则在交换计算片段中从 CoinGecko 获取。
推荐的默认值(如果需要,可通过环境变量覆盖):
bash
export BASEMAINNETRPC=${BASEMAINNETRPC:-https://mainnet.base.org}
export GBMDIAMOND=${GBMDIAMOND:-0x80320A0000C7A6a34086E2ACAD6915Ff57FfDA31}
export GHST=${GHST:-0xcD2F22236DD9Dfe2356D7C543161D4d260FD9BcB}
export USDC=${USDC:-0x833589fCD6eDb6E08f4c7C32D4f71b54BDA02913}
export GBMSUBGRAPHURL=${GBMSUBGRAPHURL:-https://api.goldsky.com/api/public/project_cmh3flagm0001r4p25foufjtt/subgraphs/aavegotchi-gbm-baazaar-base/prod/gn}
export DRYRUN=${DRYRUN:-1}
export SLIPPAGEPCT=${SLIPPAGEPCT:-1}
注意:
- - 下面的命令使用 ~/.foundry/bin/cast,以便在 cron/非交互式 shell 中工作。
查看/列出拍卖(优先使用子图)
规范查询请参见 references/subgraph.md。
按 ID 查询拍卖(快速):
bash
curl -s $GBMSUBGRAPHURL -H content-type: application/json ${GOLDSKYAPIKEY:+-H Authorization: Bearer $GOLDSKYAPIKEY} --data {
query:query($id:ID!){ auction(id:$id){ id type contractAddress tokenId quantity seller highestBid highestBidder totalBids startsAt endsAt claimAt claimed cancelled presetId category buyNowPrice startBidPrice } },
variables:{id:}
}
活跃拍卖(即将结束的优先):
bash
NOW=$(date +%s)
curl -s $GBMSUBGRAPHURL -H content-type: application/json ${GOLDSKYAPIKEY:+-H Authorization: Bearer $GOLDSKYAPIKEY} --data {
\query\:\query(\$now:BigInt!){ auctions(first:20, orderBy: endsAt, orderDirection: asc, where:{claimed:false, cancelled:false, startsAtlte:\$now, endsAtgt:\$now}){ id type contractAddress tokenId quantity highestBid highestBidder totalBids startsAt endsAt claimAt presetId category seller } }\,
\variables\:{\now\:\$NOW\}
}
链上验证(出价/发送前必需)
链上的真实数据源是 GBM 钻石合约。
确认核心拍卖字段(完整结构体解码):
bash
~/.foundry/bin/cast call $GBM_DIAMOND \
getAuctionInfo(uint256)((address,uint96,address,uint88,uint88,bool,bool,address,(uint80,uint80,uint56,uint8,bytes4,uint256,uint96,uint96),(uint64,uint64,uint64,uint64,uint256),uint96,uint96)) \
\
--rpc-url $BASEMAINNETRPC
有用的单个获取器:
bash
~/.foundry/bin/cast call $GBMDIAMOND getAuctionHighestBid(uint256)(uint256) ID> --rpc-url $BASEMAINNETRPC
~/.foundry/bin/cast call $GBMDIAMOND getAuctionHighestBidder(uint256)(address) ID> --rpc-url $BASEMAINNETRPC
~/.foundry/bin/cast call $GBMDIAMOND getAuctionStartTime(uint256)(uint256) ID> --rpc-url $BASEMAINNETRPC
~/.foundry/bin/cast call $GBMDIAMOND getAuctionEndTime(uint256)(uint256) ID> --rpc-url $BASEMAINNETRPC
~/.foundry/bin/cast call $GBMDIAMOND getContractAddress(uint256)(address) ID> --rpc-url $BASEMAINNETRPC
~/.foundry/bin/cast call $GBMDIAMOND getTokenId(uint256)(uint256) ID> --rpc-url $BASEMAINNETRPC
~/.foundry/bin/cast call $GBMDIAMOND getTokenKind(uint256)(bytes4) ID> --rpc-url $BASEMAINNETRPC
创建拍卖
链上方法:
- - createAuction((uint80,uint80,uint56,uint8,bytes4,uint256,uint96,uint96),address