Smart contracts power DeFi, but they're also the wild west of crypto — and letting an AI agent call arbitrary contracts is like handing it the keys to your entire portfolio. Most wallet systems for AI agents rely on blacklists or spending limits, but what if your agent encounters a malicious contract that wasn't on anyone's radar? WAIaaS flips the script with CONTRACT_WHITELIST policies that enforce default-deny security: your agent can only interact with contracts you've explicitly pre-approved, and everything else gets blocked at the policy layer.
Why Contract Whitelisting Matters
AI agents are pattern-matching machines, not security auditors. They'll happily interact with a contract that looks legitimate — same function signatures, similar rewards — without understanding that it's a honeypot designed to drain wallets. Traditional spending limits don't help here because the malicious contract might only ask for a small amount initially, then use that approval for a larger drain later.
The stakes are particularly high for trading and DeFi agents. These systems need to interact with protocols like Uniswap, Aave, or Jupiter, but they shouldn't have carte blanche to call any contract they discover. A compromised agent or a clever prompt injection could redirect funds to an attacker's contract, and by the time you notice, it's too late.
Default-deny security flips this around: instead of trying to identify every bad contract (an impossible task), you identify the handful of contracts your agent actually needs, whitelist only those, and block everything else. It's the principle of least privilege applied to smart contract interactions.
How CONTRACT_WHITELIST Works in WAIaaS
WAIaaS implements contract whitelisting through its policy engine, which operates in the transaction pipeline before any signing or execution occurs. When your agent attempts to interact with a smart contract, the policy engine checks the target address against your whitelist. If the contract isn't explicitly allowed, the transaction gets denied immediately — no gas spent, no funds at risk.
The policy enforces default-deny behavior. This means that without a CONTRACT_WHITELIST policy configured, all contract calls are blocked. Your agent can only perform basic transfers until you explicitly define which protocols it's allowed to use.
Here's how to create a CONTRACT_WHITELIST policy:
curl -X POST http://localhost:3100/v1/policies \
-H 'Content-Type: application/json' \
-H 'X-Master-Password: <password>' \
-d '{
"walletId": "<wallet-uuid>",
"type": "CONTRACT_WHITELIST",
"rules": {
"contracts": [
{
"address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4",
"name": "Jupiter Aggregator",
"chain": "solana"
},
{
"address": "0xE592427A0AEce92De3Edee1F18E0157C05861564",
"name": "Uniswap V3 Router",
"chain": "ethereum"
},
{
"address": "0x7d2768dE32b0b80b7a3454c06BdAc94A69DDc7A9",
"name": "Aave Lending Pool",
"chain": "ethereum"
}
]
}
}'
This policy creates an explicit allowlist of three contracts: Jupiter for Solana token swaps, Uniswap V3 for Ethereum swaps, and Aave for lending. Your agent can interact with these specific addresses, but any attempt to call other contracts — even legitimate ones — will be blocked.
The policy integrates with WAIaaS's 7-stage transaction pipeline. When your agent submits a transaction, it passes through validation, authentication, and then hits the policy stage where CONTRACT_WHITELIST rules are enforced. If the target address isn't on the list, the transaction gets denied before reaching the execution stage.
You can combine CONTRACT_WHITELIST with other policies for defense-in-depth. For example, pairing it with SPENDING_LIMIT creates both address-based and amount-based restrictions:
# First, create spending limits
curl -X POST http://localhost:3100/v1/policies \
-H 'Content-Type: application/json' \
-H 'X-Master-Password: <password>' \
-d '{
"walletId": "<wallet-uuid>",
"type": "SPENDING_LIMIT",
"rules": {
"instant_max_usd": 10,
"notify_max_usd": 100,
"delay_max_usd": 1000,
"delay_seconds": 300
}
}'
# Then add contract whitelist
curl -X POST http://localhost:3100/v1/policies \
-H 'Content-Type: application/json' \
-H 'X-Master-Password: <password>' \
-d '{
"walletId": "<wallet-uuid>",
"type": "CONTRACT_WHITELIST",
"rules": {
"contracts": [
{"address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4", "name": "Jupiter", "chain": "solana"}
]
}
}'
Now your agent faces both restrictions: it can only call Jupiter, and transactions over $10 will trigger notifications, delays, or approvals based on the amount.
METHOD_WHITELIST for Fine-Grained Control
For even more precise control, you can combine CONTRACT_WHITELIST with METHOD_WHITELIST to restrict which functions your agent can call on approved contracts. This is particularly useful for complex protocols where you want to allow specific operations but block others.
curl -X POST http://localhost:3100/v1/policies \
-H 'Content-Type: application/json' \
-H 'X-Master-Password: <password>' \
-d '{
"walletId": "<wallet-uuid>",
"type": "METHOD_WHITELIST",
"rules": {
"methods": [
"0x38ed1739", // swapExactTokensForTokens
"0x8803dbee" // swapTokensForExactTokens
]
}
}'
This allows your agent to perform swaps on whitelisted contracts but blocks other functions like liquidity provision or governance actions.
Real-World Integration Patterns
Most AI trading agents need to interact with a small, predictable set of protocols. A typical DeFi agent might only need Jupiter for Solana swaps, Lido for ETH staking, and Aave for lending. By whitelisting just these contracts, you eliminate 99% of the attack surface while preserving all the functionality your agent actually uses.
Here's how this looks in practice with the WAIaaS SDK:
import { WAIaaSClient } from '@waiaas/sdk';
const client = new WAIaaSClient({
baseUrl: 'http://127.0.0.1:3100',
sessionToken: process.env.WAIAAS_SESSION_TOKEN,
});
try {
// This works - Jupiter is whitelisted
const swapResult = await client.executeAction('jupiter-swap', 'swap', {
inputMint: 'So11111111111111111111111111111111111111112', // SOL
outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
amount: '1000000000' // 1 SOL
});
console.log(`Swap initiated: ${swapResult.id}`);
// This fails - random contract not on whitelist
const maliciousCall = await client.callContract({
to: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef',
data: '0x...'
});
} catch (error) {
console.log(`Blocked by policy: ${error.message}`);
// Error: Transaction denied by CONTRACT_WHITELIST policy
}
The beauty of this approach is that your agent code doesn't need to change. It attempts the transaction normally, and the policy layer handles the security enforcement. This makes it easy to add whitelisting to existing agents without refactoring.
Multi-Chain Contract Management
WAIaaS supports contract whitelisting across multiple chains simultaneously. Each contract in your whitelist specifies its chain, so you can create policies that span Ethereum, Solana, Polygon, and other supported networks:
{
"contracts": [
{"address": "0xE592427A0AEce92De3Edee1F18E0157C05861564", "name": "Uniswap V3", "chain": "ethereum"},
{"address": "0xE592427A0AEce92De3Edee1F18E0157C05861564", "name": "Uniswap V3", "chain": "polygon"},
{"address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4", "name": "Jupiter", "chain": "solana"}
]
}
This is particularly important for cross-chain agents that need to maintain consistent security policies across different networks. The same whitelist logic applies regardless of which chain your agent is operating on.
Quick Start: Locking Down Your Agent
Here's how to set up contract whitelisting for a new agent in under 5 minutes:
- Start WAIaaS and create a wallet:
npm install -g @waiaas/cli
waiaas init
waiaas start
waiaas wallet create --name "trading-agent" --chain solana
- Create a session for your agent:
waiaas session create --wallet-id <wallet-uuid>
# Copy the returned session token
- Set up contract whitelist policy:
curl -X POST http://localhost:3100/v1/policies \
-H 'Content-Type: application/json' \
-H 'X-Master-Password: <your-password>' \
-d '{
"walletId": "<wallet-uuid>",
"type": "CONTRACT_WHITELIST",
"rules": {
"contracts": [
{"address": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4", "name": "Jupiter", "chain": "solana"}
]
}
}'
- Test the restriction:
# This should work (Jupiter is whitelisted)
curl -X POST http://localhost:3100/v1/actions/jupiter-swap/swap \
-H "Authorization: Bearer <session-token>" \
-d '{"inputMint": "So11111111111111111111111111111111111111112", "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "amount": "1000000"}'
# This should fail (random contract)
curl -X POST http://localhost:3100/v1/transactions/send \
-H "Authorization: Bearer <session-token>" \
-d '{"type": "ContractCall", "to": "randomcontractaddress", "data": "0x"}'
-
Monitor and adjust: Use the admin UI at
http://localhost:3100/adminto view policy enforcement logs and add new contracts as needed.
Your agent is now locked down to only interact with Jupiter for token swaps. Any attempt to call other contracts — malicious or otherwise — gets blocked automatically.
What's Next
CONTRACT_WHITELIST is one of 21 policy types in WAIaaS's security framework. Combined with spending limits, time restrictions, and human approval workflows, it creates multiple layers of protection for AI agents handling crypto assets. To learn more about implementing comprehensive security for your agent, check out the full documentation at the GitHub repository and explore the other policy types available in the system.
Ready to lock down your AI agent? Get started with WAIaaS at GitHub or visit waiaas.ai for more information.
Top comments (0)