Aavegotchi GBM Skill
/install aavegotchi-gbm-skill
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 be8453.
- 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
highestBidmatches thehighestBidyou pass intocommitBid/swapAndCommitBid. - ensure token params match (token contract, token id, quantity).
- ensure the onchain
- 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
"\x3CAUCTION_ID>"to avoid accidental shell interpolation. Replace them with literal values only after validation.
Quick validators (replace the placeholder values):
python3 - \x3C\x3C'PY'
import re
auction_id = "\x3CAUCTION_ID>" # digits only
token_contract = "\x3CTOKEN_CONTRACT_ADDRESS>" # 0x + 40 hex chars
token_id = "\x3CTOKEN_ID>" # digits only
amount = "\x3CTOKEN_AMOUNT>" # digits only
if not re.fullmatch(r"[0-9]+", auction_id):
raise SystemExit("AUCTION_ID must be base-10 digits only")
if not re.fullmatch(r"0x[a-fA-F0-9]{40}", token_contract):
raise SystemExit("TOKEN_CONTRACT_ADDRESS must be a 0x + 40-hex address")
if not re.fullmatch(r"[0-9]+", token_id):
raise SystemExit("TOKEN_ID must be base-10 digits only")
if not re.fullmatch(r"[0-9]+", amount):
raise SystemExit("TOKEN_AMOUNT must be base-10 digits only")
print("ok")
PY
Required Setup
Required env vars:
PRIVATE_KEY: EOA private key used forcast send(never print/log).FROM_ADDRESS: EOA address that owns NFTs and will submit txs.BASE_MAINNET_RPC: RPC URL. If unset, usehttps://mainnet.base.org.GBM_SUBGRAPH_URL: Goldsky subgraph endpoint for auctions.
Optional env vars:
DRY_RUN:1(default) to only simulate viacast call. Set to0to broadcast viacast send.RECIPIENT_ADDRESS: for swap flows; receives any excess GHST refunded by the contract. Defaults toFROM_ADDRESS.GOLDSKY_API_KEY: optional; if set, includeAuthorization: Bearer ...header in subgraph calls.SLIPPAGE_PCT: defaults to1(%); used inswapAmountestimate math.GHST_USD_PRICE,ETH_USD_PRICE: optional overrides; if unset, fetch from CoinGecko in the swap math snippets.
Recommended defaults (override via env if needed):
export BASE_MAINNET_RPC="${BASE_MAINNET_RPC:-https://mainnet.base.org}"
export GBM_DIAMOND="${GBM_DIAMOND:-0x80320A0000C7A6a34086E2ACAD6915Ff57FfDA31}"
export GHST="${GHST:-0xcD2F22236DD9Dfe2356D7C543161D4d260FD9BcB}"
export USDC="${USDC:-0x833589fCD6eDb6E08f4c7C32D4f71b54BDA02913}"
export GBM_SUBGRAPH_URL="${GBM_SUBGRAPH_URL:-https://api.goldsky.com/api/public/project_cmh3flagm0001r4p25foufjtt/subgraphs/aavegotchi-gbm-baazaar-base/prod/gn}"
export DRY_RUN="${DRY_RUN:-1}"
export SLIPPAGE_PCT="${SLIPPAGE_PCT:-1}"
Notes:
- Commands below use
~/.foundry/bin/castso they work in cron/non-interactive shells.
View / List Auctions (Subgraph First)
See references/subgraph.md for canonical queries.
Auction by id (quick):
curl -s "$GBM_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --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":"\x3CAUCTION_ID>"}
}'
Active auctions (ends soonest first):
NOW=$(date +%s)
curl -s "$GBM_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data "{
\"query\":\"query(\$now:BigInt!){ auctions(first:20, orderBy: endsAt, orderDirection: asc, where:{claimed:false, cancelled:false, startsAt_lte:\$now, endsAt_gt:\$now}){ id type contractAddress tokenId quantity highestBid highestBidder totalBids startsAt endsAt claimAt presetId category seller } }\",
\"variables\":{\"now\":\"$NOW\"}
}"
Onchain Verification (Required Before Bids / Sends)
The onchain source of truth is the GBM diamond.
Confirm core auction fields (full struct decode):
~/.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))' \
"\x3CAUCTION_ID>" \
--rpc-url "$BASE_MAINNET_RPC"
Useful individual getters:
~/.foundry/bin/cast call "$GBM_DIAMOND" 'getAuctionHighestBid(uint256)(uint256)' "\x3CAUCTION_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$GBM_DIAMOND" 'getAuctionHighestBidder(uint256)(address)' "\x3CAUCTION_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$GBM_DIAMOND" 'getAuctionStartTime(uint256)(uint256)' "\x3CAUCTION_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$GBM_DIAMOND" 'getAuctionEndTime(uint256)(uint256)' "\x3CAUCTION_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$GBM_DIAMOND" 'getContractAddress(uint256)(address)' "\x3CAUCTION_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$GBM_DIAMOND" 'getTokenId(uint256)(uint256)' "\x3CAUCTION_ID>" --rpc-url "$BASE_MAINNET_RPC"
~/.foundry/bin/cast call "$GBM_DIAMOND" 'getTokenKind(uint256)(bytes4)' "\x3CAUCTION_ID>" --rpc-url "$BASE_MAINNET_RPC"
Create Auction
Onchain method:
createAuction((uint80,uint80,uint56,uint8,bytes4,uint256,uint96,uint96),address,uint256)(uint256)
High-level steps:
- 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)
- ERC721/1155:
- Choose
InitiatorInfo:startTimemust be in the future.endTime - startTimemust be between 3600 and 604800 seconds (1h to 7d).tokenKindis0x73ad2146(ERC721) or0x973bb640(ERC1155).buyItNowPriceoptional;startingBidoptional (if nonzero, you must approve GHST for the 4% prepaid fee).
- Simulate with
cast callusing--from "$FROM_ADDRESS". - Broadcast with
cast sendonly when explicitly instructed (DRY_RUN=0). - Post-tx: query subgraph for newest seller auctions and match
(contractAddress, tokenId).
Simulate create (ERC721 example):
~/.foundry/bin/cast call "$GBM_DIAMOND" \
'createAuction((uint80,uint80,uint56,uint8,bytes4,uint256,uint96,uint96),address,uint256)(uint256)' \
"(\x3CSTART_TIME>,\x3CEND_TIME>,1,\x3CCATEGORY>,0x73ad2146,\x3CTOKEN_ID>,\x3CBUY_NOW_GHST_WEI>,\x3CSTARTING_BID_GHST_WEI>)" \
"\x3CERC721_CONTRACT_ADDRESS>" "\x3CPRESET_ID>" \
--from "$FROM_ADDRESS" \
--rpc-url "$BASE_MAINNET_RPC"
Broadcast create (only when explicitly instructed):
~/.foundry/bin/cast send "$GBM_DIAMOND" \
'createAuction((uint80,uint80,uint56,uint8,bytes4,uint256,uint96,uint96),address,uint256)(uint256)' \
"(\x3CSTART_TIME>,\x3CEND_TIME>,1,\x3CCATEGORY>,0x73ad2146,\x3CTOKEN_ID>,\x3CBUY_NOW_GHST_WEI>,\x3CSTARTING_BID_GHST_WEI>)" \
"\x3CERC721_CONTRACT_ADDRESS>" "\x3CPRESET_ID>" \
--private-key "$PRIVATE_KEY" \
--rpc-url "$BASE_MAINNET_RPC"
Post-create (find your newest auctions and confirm):
curl -s "$GBM_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{
"query":"query($seller:Bytes!){ auctions(first:10, orderBy: createdAt, orderDirection: desc, where:{seller:$seller}){ id type contractAddress tokenId quantity createdAt startsAt endsAt claimed cancelled } }",
"variables":{"seller":"\x3CFROM_ADDRESS_LOWERCASE>"}
}'
Cancel Auction
Onchain method:
cancelAuction(uint256)
Steps:
- 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:
~/.foundry/bin/cast call "$GBM_DIAMOND" 'cancelAuction(uint256)' "\x3CAUCTION_ID>" \
--from "$FROM_ADDRESS" \
--rpc-url "$BASE_MAINNET_RPC"
Broadcast (only when explicitly instructed):
~/.foundry/bin/cast send "$GBM_DIAMOND" 'cancelAuction(uint256)' "\x3CAUCTION_ID>" \
--private-key "$PRIVATE_KEY" \
--rpc-url "$BASE_MAINNET_RPC"
Bid With GHST (commitBid)
Onchain method:
commitBid(uint256,uint256,uint256,address,uint256,uint256,bytes)(lastbytesis ignored; pass0x)
Steps:
- Subgraph: fetch auction fields (id, contractAddress, tokenId, quantity, highestBid, startsAt, endsAt, claimed/cancelled).
- Onchain: refetch
highestBidand token params; you must pass the exact current onchainhighestBidor it revertsUnmatchedHighestBid. - Compute a safe minimum next bid using
references/bid-math.md(uses onchainbidDecimals+stepMin). - Ensure GHST allowance to the GBM diamond covers
bidAmount. - Simulate via
cast call(optional but recommended). - Broadcast only when explicitly instructed.
Simulate:
~/.foundry/bin/cast call "$GBM_DIAMOND" \
'commitBid(uint256,uint256,uint256,address,uint256,uint256,bytes)' \
"\x3CAUCTION_ID>" "\x3CBID_AMOUNT_GHST_WEI>" "\x3CHIGHEST_BID_GHST_WEI>" "\x3CTOKEN_CONTRACT_ADDRESS>" "\x3CTOKEN_ID>" "\x3CTOKEN_AMOUNT>" 0x \
--from "$FROM_ADDRESS" \
--rpc-url "$BASE_MAINNET_RPC"
Broadcast (only when explicitly instructed):
~/.foundry/bin/cast send "$GBM_DIAMOND" \
'commitBid(uint256,uint256,uint256,address,uint256,uint256,bytes)' \
"\x3CAUCTION_ID>" "\x3CBID_AMOUNT_GHST_WEI>" "\x3CHIGHEST_BID_GHST_WEI>" "\x3CTOKEN_CONTRACT_ADDRESS>" "\x3CTOKEN_ID>" "\x3CTOKEN_AMOUNT>" 0x \
--private-key "$PRIVATE_KEY" \
--rpc-url "$BASE_MAINNET_RPC"
Bid With USDC Swap (swapAndCommitBid)
Onchain method:
swapAndCommitBid((address,uint256,uint256,uint256,address,uint256,uint256,uint256,address,uint256,uint256,bytes))
Struct fields (in order):
tokenIn(USDC)swapAmount(USDC 6dp)minGhstOut(GHST wei; must be >= bidAmount)swapDeadline(unix; must be \x3C= now + 86400)recipient(refund receiver for excess GHST)auctionIDbidAmount(GHST wei)highestBid(must match onchain)tokenContracttokenIDamount(tokenAmount/quantity)_signature(ignored; pass0x)
Compute swapAmount estimate in references/swap-math.md.
Simulate:
~/.foundry/bin/cast call "$GBM_DIAMOND" \
'swapAndCommitBid((address,uint256,uint256,uint256,address,uint256,uint256,uint256,address,uint256,uint256,bytes))' \
"($USDC,\x3CSWAP_AMOUNT_USDC_6DP>,\x3CMIN_GHST_OUT_GHST_WEI>,\x3CSWAP_DEADLINE_UNIX>,${RECIPIENT_ADDRESS:-$FROM_ADDRESS},\x3CAUCTION_ID>,\x3CBID_AMOUNT_GHST_WEI>,\x3CHIGHEST_BID_GHST_WEI>,\x3CTOKEN_CONTRACT_ADDRESS>,\x3CTOKEN_ID>,\x3CTOKEN_AMOUNT>,0x)" \
--from "$FROM_ADDRESS" \
--rpc-url "$BASE_MAINNET_RPC"
Broadcast (only when explicitly instructed):
~/.foundry/bin/cast send "$GBM_DIAMOND" \
'swapAndCommitBid((address,uint256,uint256,uint256,address,uint256,uint256,uint256,address,uint256,uint256,bytes))' \
"($USDC,\x3CSWAP_AMOUNT_USDC_6DP>,\x3CMIN_GHST_OUT_GHST_WEI>,\x3CSWAP_DEADLINE_UNIX>,${RECIPIENT_ADDRESS:-$FROM_ADDRESS},\x3CAUCTION_ID>,\x3CBID_AMOUNT_GHST_WEI>,\x3CHIGHEST_BID_GHST_WEI>,\x3CTOKEN_CONTRACT_ADDRESS>,\x3CTOKEN_ID>,\x3CTOKEN_AMOUNT>,0x)" \
--private-key "$PRIVATE_KEY" \
--rpc-url "$BASE_MAINNET_RPC"
Bid With ETH Swap (swapAndCommitBid)
Same method as above, but:
tokenIn = 0x0000000000000000000000000000000000000000--value \x3CSWAP_AMOUNT_WEI>must equal theswapAmountyou pass inside the tuple.
Broadcast (only when explicitly instructed):
~/.foundry/bin/cast send "$GBM_DIAMOND" \
'swapAndCommitBid((address,uint256,uint256,uint256,address,uint256,uint256,uint256,address,uint256,uint256,bytes))' \
"(0x0000000000000000000000000000000000000000,\x3CSWAP_AMOUNT_WEI>,\x3CMIN_GHST_OUT_GHST_WEI>,\x3CSWAP_DEADLINE_UNIX>,${RECIPIENT_ADDRESS:-$FROM_ADDRESS},\x3CAUCTION_ID>,\x3CBID_AMOUNT_GHST_WEI>,\x3CHIGHEST_BID_GHST_WEI>,\x3CTOKEN_CONTRACT_ADDRESS>,\x3CTOKEN_ID>,\x3CTOKEN_AMOUNT>,0x)" \
--value "\x3CSWAP_AMOUNT_WEI>" \
--private-key "$PRIVATE_KEY" \
--rpc-url "$BASE_MAINNET_RPC"
Claim Auction
Onchain methods:
claim(uint256)batchClaim(uint256[])
Claim readiness:
- Auction owner can claim at
now >= endsAt. - Highest bidder can claim at
now >= endsAt + cancellationTime.cancellationTimeis readable from storage slot 12 (seereferences/recipes.md).- Subgraph may provide
claimAt(if populated), but always verify onchain.
Simulate:
~/.foundry/bin/cast call "$GBM_DIAMOND" 'claim(uint256)' "\x3CAUCTION_ID>" \
--from "$FROM_ADDRESS" \
--rpc-url "$BASE_MAINNET_RPC"
Broadcast (only when explicitly instructed):
~/.foundry/bin/cast send "$GBM_DIAMOND" 'claim(uint256)' "\x3CAUCTION_ID>" \
--private-key "$PRIVATE_KEY" \
--rpc-url "$BASE_MAINNET_RPC"
Optional: Buy Now
Onchain methods:
buyNow(uint256)swapAndBuyNow((address,uint256,uint256,uint256,address,uint256))
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)
- Subgraph reachable (introspection lists
auction,auctions,bid,bids):
curl -s "$GBM_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{ "query":"{ __schema { queryType { fields { name } } } }" }' \
| python3 -c 'import json,sys; f=[x[\"name\"] for x in json.load(sys.stdin)[\"data\"][\"__schema\"][\"queryType\"][\"fields\"]]; print([n for n in f if n in (\"auction\",\"auctions\",\"bid\",\"bids\")])'
- Subgraph data sane:
curl -s "$GBM_SUBGRAPH_URL" -H 'content-type: application/json' ${GOLDSKY_API_KEY:+-H "Authorization: Bearer $GOLDSKY_API_KEY"} --data '{\"query\":\"query($id:ID!){ auction(id:$id){ id contractAddress tokenId } }\",\"variables\":{\"id\":\"0\"}}'
- Onchain reachable + matches subgraph:
~/.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))' \
0 \
--rpc-url "$BASE_MAINNET_RPC"
Common Failure Modes
UnmatchedHighestBid: you passed a stalehighestBidparam. Refetch onchain and retry.InvalidAuctionParams: token contract / id / amount mismatch. Refetch and verify.AuctionNotStarted/AuctionEnded: timing mismatch. CheckstartsAt/endsAt(subgraph + onchain).AuctionClaimed: already claimed or cancelled. Checkclaimed(subgraph + onchain).BiddingNotAllowed: diamond paused, contract bidding disabled, or re-entrancy lock. Refetch onchain state.- Swap errors:
LibTokenSwap: swapAmount must be > 0LibTokenSwap: deadline expiredLibTokenSwap: Insufficient output amount(increaseswapAmountor slippage)
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install aavegotchi-gbm-skill - 安装完成后,直接呼叫该 Skill 的名称或使用
/aavegotchi-gbm-skill触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
Aavegotchi GBM Skill 是什么?
View, create, cancel, bid, and claim Aavegotchi GBM auctions on Base mainnet (8453). Subgraph-first discovery (Goldsky), with onchain verification + executio... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 664 次。
如何安装 Aavegotchi GBM Skill?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install aavegotchi-gbm-skill」即可一键安装,无需额外配置。
Aavegotchi GBM Skill 是免费的吗?
是的,Aavegotchi GBM Skill 完全免费(开源免费),可自由下载、安装和使用。
Aavegotchi GBM Skill 支持哪些平台?
Aavegotchi GBM Skill 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。
谁开发了 Aavegotchi GBM Skill?
由 cinnabarhorse(@cinnabarhorse)开发并维护,当前版本 v0.1.0。