upvoting-on-abstract
Upvoting on Abstract
The Abstract Portal has an on-chain voting system where users spend ETH to upvote apps each epoch. Votes signal app quality and contribute to Portal XP.
Operating Rules
- Check the vote cost with
voteCost()before submitting a vote — the cost is set per epoch and may change. - Check remaining votes with
userVotesRemaining(address)before voting. - The
voteForAppfunction is payable — include the vote cost asvalue. - Each user can vote for each app only once per epoch (
AlreadyVotedForerror). - Preview every vote with
--dry-runbefore execution. - Read references/voting-contract.md for the full contract interface and error handling.
Contract
| Network | Address |
|---|---|
| Mainnet | 0x3b50de27506f0a8c1f4122a1e6f470009a76ce2a |
ABI Format
The AGW CLI requires full JSON ABI objects, not human-readable strings. Every abi array element must be an object with type, name, inputs, outputs, and stateMutability fields.
Task Map
Check vote cost and current epoch
agw contract write --json '{
"address": "0x3b50de27506f0a8c1f4122a1e6f470009a76ce2a",
"abi": [{"type":"function","name":"voteCost","stateMutability":"view","inputs":[],"outputs":[{"name":"","type":"uint96"}]}],
"functionName": "voteCost",
"args": []
}' --dry-run
agw contract write --json '{
"address": "0x3b50de27506f0a8c1f4122a1e6f470009a76ce2a",
"abi": [{"type":"function","name":"currentEpoch","stateMutability":"view","inputs":[],"outputs":[{"name":"","type":"uint256"}]}],
"functionName": "currentEpoch",
"args": []
}' --dry-run
Check remaining votes
agw contract write --json '{
"address": "0x3b50de27506f0a8c1f4122a1e6f470009a76ce2a",
"abi": [{"type":"function","name":"userVotesRemaining","stateMutability":"view","inputs":[{"name":"user","type":"address"}],"outputs":[{"name":"","type":"uint256"}]}],
"functionName": "userVotesRemaining",
"args": ["<YOUR_ADDRESS>"]
}' --dry-run
Vote for an app
Replace <APP_ID> with the Portal app ID (e.g., 25 for Onchain Heroes) and <VOTE_COST> with the value from voteCost():
agw contract write --json '{
"address": "0x3b50de27506f0a8c1f4122a1e6f470009a76ce2a",
"abi": [{"type":"function","name":"voteForApp","stateMutability":"payable","inputs":[{"name":"appId","type":"uint256"}],"outputs":[]}],
"functionName": "voteForApp",
"args": ["<APP_ID>"],
"value": "<VOTE_COST>"
}' --dry-run
Execute only after confirming the preview: replace --dry-run with --execute.
Check votes for a specific app
agw contract write --json '{
"address": "0x3b50de27506f0a8c1f4122a1e6f470009a76ce2a",
"abi": [{"type":"function","name":"getVotesForApp","stateMutability":"view","inputs":[{"name":"appId","type":"uint256"},{"name":"epoch","type":"uint256"}],"outputs":[{"name":"","type":"uint256"}]}],
"functionName": "getVotesForApp",
"args": ["<APP_ID>", "<EPOCH>"]
}' --dry-run
Use currentEpoch() to get the current epoch number first.
Check which apps a user voted for
agw contract write --json '{
"address": "0x3b50de27506f0a8c1f4122a1e6f470009a76ce2a",
"abi": [{"type":"function","name":"getUserVotes","stateMutability":"view","inputs":[{"name":"user","type":"address"},{"name":"epoch","type":"uint256"}],"outputs":[{"name":"","type":"uint256[]"}]}],
"functionName": "getUserVotes",
"args": ["<USER_ADDRESS>", "<EPOCH>"]
}' --dry-run
Returns an array of app IDs the user has voted for this epoch.
Voting Workflow
- Check vote cost:
voteCost()→ returns cost in wei - Check remaining votes:
userVotesRemaining(address)→ returns count - Find the app ID via
agw portal apps listoragw app list - Preview the vote:
voteForApp(appId)with--dry-runandvalueset to vote cost - Execute after confirmation:
--execute - Verify:
getUserVotes(address, epoch)to confirm your vote was recorded
Error Handling
| Error | Cause | Fix |
|---|---|---|
InvalidValue |
Sent wrong ETH amount | Send exactly voteCost() as value |
VotingNotActive |
Voting not open this epoch | Wait for next epoch |
AppNotActive |
App not eligible for votes | Verify app ID via Portal |
AlreadyVotedFor |
Already voted for this app this epoch | Choose a different app |
UsedAllVotes |
No remaining votes this epoch | Wait for next epoch |
Escalation
- Route app discovery to
discovering-abstract-portal. - Route wallet balance checks to
reading-agw-wallet. - Route transaction safety to
executing-agw-transactions.
More from abstract-foundation/agw-cli
mining-with-bigcoin
Interact with the Bigcoin virtual mining game on Abstract — buy facilities, purchase miners, claim rewards, check hashrate, and manage mining operations. Use when a user wants to play Bigcoin, mine $BIG tokens, buy a facility or miner, claim mining rewards, check pending rewards, view hashrate, upgrade their facility, sell miners, or interact with the Bigcoin game contracts on Abstract. Trigger for requests mentioning Bigcoin, $BIG, BIG token, virtual mining, hashrate, facility, miner purchase, mining rewards, claim BIG, or Bigcoin game on Abstract.
22reading-agw-wallet
Read AGW wallet identity, balances, and token inventory with field trimming and pagination. Use when a user wants to know which wallet is linked, inspect balances, list tokens, confirm the current account before another workflow, or gather read-only wallet context without blowing the context window. Trigger for requests mentioning `agw wallet address`, `agw wallet balances`, `agw wallet tokens list`, portfolio inspection, token inventory, or linked wallet identity.
21trading-on-uniswap
Compose AGW wallet and contract commands for token swaps, price quotes, and liquidity on Abstract via Uniswap V2 and V3. Use when a user wants to trade tokens, swap ETH for USDC, swap USDC for ETH, check token prices, get swap quotes, add or remove liquidity, or interact with any Uniswap contract on Abstract. Trigger for requests mentioning swap, trade, exchange, Uniswap, DEX, liquidity pool, price quote, token pair, amountOut, slippage, or AGW trading actions on Abstract mainnet or testnet.
21authenticating-with-agw
Bootstrap, inspect, troubleshoot, and revoke AGW sessions through the companion approval flow. Use when a user needs to connect this machine to an AGW wallet, check session readiness, diagnose missing signer or delegated-access issues, inspect local session state, or explicitly revoke access. Trigger for requests mentioning `agw auth init`, `agw session status`, `agw session doctor`, onboarding, companion approval, or session revoke.
21bridging-to-abstract
Guide users through bridging assets to and from Abstract using the native bridge or third-party bridges (Relay, Stargate, Jumper, Symbiosis, thirdweb, deBridge). Use when a user wants to move funds onto Abstract, bridge ETH or tokens from Ethereum or another chain, withdraw from Abstract to L1, get a bridge quote, fund their Abstract wallet from another network, or needs guidance on bridge timing and costs. Trigger for requests mentioning bridge, bridging, deposit, withdraw, fund wallet, move funds, cross-chain transfer, L1 to L2, or any of the bridge providers (Relay, Stargate, Jumper, Symbiosis, deBridge).
21executing-agw-transactions
Apply preview-first execution rules to AGW signing, sends, batched calls, token transfers, contract writes, and deployments. Use when a user wants to sign data, simulate a transaction, broadcast a transaction, transfer tokens, write a contract, deploy a contract, or build one of those payloads safely. Trigger for requests mentioning `agw tx`, `agw contract`, signing, dry-run, execute, preview, transfer, contract write, or deployment.
21