veriql-cdp-policy
v0.1.0
Published
Keep a Coinbase CDP Policy Engine policy in step with the free Veriql denylist (OFAC SDN + Drain Watch), so a CDP server wallet refuses to pay or approve a listed address. Verified with CDP's own policy simulator.
Downloads
359
Maintainers
Readme
veriql-cdp-policy
Stop a Coinbase CDP server wallet from paying a sanctioned or known-scam address.
This keeps a CDP Policy Engine policy in step with the free Veriql denylist: the US Treasury OFAC SDN list plus Drain Watch, a list of known drainer and scam addresses. Once the policy is attached, the wallet refuses to send to a listed address, including ETH, ERC-20 tokens, SOL and SPL tokens. It also refuses to grant a listed address an ERC-20 allowance. An AI agent using the wallet cannot be talked into paying one, because CDP refuses to sign.
export CDP_API_KEY_ID=... CDP_API_KEY_SECRET=... # key needs Non-custodial > Manage (modify policies)
npx veriql-cdp-policy # dry run: fetch the feed, build the policy, write nothing
npx veriql-cdp-policy --print # also print the policy JSON
npx veriql-cdp-policy --apply # create or update the "Veriql denylist" account policy
npx veriql-cdp-policy --apply --evm-account 0x... --sol-account <address>
# attach it to those accounts and prove it works
npx veriql-cdp-policy --family evm # evm | solana | all (default)The feed refreshes daily, so run it once a day (cron, a CI schedule, or a Worker). A run that finds nothing new writes nothing.
It proves itself on CDP's own simulator
When you attach the policy to an account, the tool asks CDP's policy simulator to judge real transactions for that account. Nothing is signed or sent:
| Case | Must be | |---|---| | ETH to an unlisted address | accepted | | USDC to an unlisted address | accepted | | ETH to a listed address | rejected | | USDC to a listed address (sign and send) | rejected | | USDC approval to a listed spender | rejected | | SOL to an unlisted / listed address | accepted / rejected | | Token transfer to an unlisted / listed account | accepted / rejected |
If the policy rejects an unlisted payment, the tool pauses it immediately. A policy that blocks every payment is an outage, not protection. If a listed payment gets through, the tool reports which case failed and exits non-zero.
How the policy is built
- Recipients come from calldata, not just
to. For a USDC payment, the transaction'stofield is the token contract, so an address rule alone never sees who is being paid. The policy also reads the recipient oftransferandtransferFrom, and the spender ofapprove. Most drained wallets were emptied through an approval. - Unlisted payments keep working. Once a CDP policy has any rule for an operation, a request that matches none of them is rejected. So each operation gets one rule that accepts everything else. A matching reject always wins over an accept, so this never lets a listed address through.
- It refuses rather than truncates. CDP allows 300 addresses per criterion and 100 rules per policy. Today's feed (about 800 EVM and 110 Solana addresses) needs 45 rules. If the list ever outgrows one policy, the tool exits with an error instead of quietly dropping the end of it. Use
--familyto split it. - It never builds from a failure. If the feed answers with an error or with zero items, the tool exits and leaves your policy unchanged.
- It never replaces your policy. It manages one account policy, identified by the description
Veriql denylist. An account can hold one account policy, so if the account already has a different one, the tool refuses to attach and tells you to copy the rules (--print) into your own policy.
Limits
- Signed typed data (EIP-2612 Permit, Permit2) is not covered by this policy. Check a signing request with
POST https://veriql.app/api/v1/signature, or useveriql-agentkit'scheck_signatureaction. - A list is only as current as its last refresh. To check a single recipient live, including whether Tether or Circle has frozen it, call
GET https://veriql.app/api/v1/payee. - Not being listed means no known listing, not that an address is safe.
- Smart accounts get their policy via
cdp.evm.updateSmartAccount. The policy already includessendUserOperationrules, but this tool only attaches it to server (EOA) accounts.
Licence
MIT. The denylist itself combines US Treasury OFAC data (a US federal work) with Veriql's Drain Watch list. See https://veriql.app/drain-watch.
