Build a Portfolio Rebalancer Agent
A portfolio rebalancer watches a set of asset weights, compares them against a target allocation, and submits trades whenever the drift exceeds tolerance. On Tenzro you can deploy the entire agent without writing any Rust code — the AgentKit template ref-yield-rebalancer-v1 encodes the identity provisioning, delegation scope, drift calculation, and trade dispatch declaratively. You configure it, spawn it, and run it from the tenzro CLI.
What You'll Do
- Explore the
ref-yield-rebalancer-v1AgentKit template - Spawn a rebalancer agent with a 7-day time-bound delegation scope and hard spend caps
- Dry-run the agent against simulated prices to verify drift calculations
- Execute a live rebalance run with real on-chain trades
- Review results including delegation enforcement and trade receipts
Why Delegation-First Trading Matters
The whole point of running an autonomous trading agent is that you don't want to babysit it. But that means the security boundary needs to be the delegation scope, not your own monitoring. On Tenzro every machine identity is provisioned under a controller identity, and the controller installs a DelegationScopethat hard-caps per-transaction value, daily spend, allowed operations, and a time bound. The agent never gets a wallet without one of these scopes attached. The pattern is: compute the trade, ask the registry whether it's authorized, and only then dispatch it through the EVM. If the answer is no, the trade is silently dropped — no on-chain footprint, no wasted gas.
Step 1: Prerequisites
You need the tenzro installed and a running node to connect to. If you haven't already joined the network, do that first — tenzro join provisions your identity and wallet in a single command:
# Install the CLI (if not already installed)
cargo install --path crates/tenzro-cli
# Join the network — provisions your human identity + MPC wallet
tenzro join
# Verify your wallet is funded (request testnet tokens if needed)
tenzro wallet balanceYou should see your controller DID (format did:tenzro:human:...) and a wallet balance. If you need testnet TNZO, hit the faucet:
curl -X POST https://api.tenzro.network/faucet \
-H "Content-Type: application/json" \
-d '{"address": "<your-wallet-address>"}'Step 2: Explore the Yield-Rebalancer Template
AgentKit ships pre-built agent templates. Start by listing what's available, then inspect the rebalancer template to understand its configuration surface:
# List all available AgentKit templates
tenzro agent list-templatesYou'll see ref-yield-rebalancer-v1 in the output. Pull its full specification:
# Inspect the rebalancer template
tenzro agent get-template ref-yield-rebalancer-v1The output shows every configurable parameter:
Template: ref-yield-rebalancer-v1
Description: Autonomous portfolio rebalancer with delegation-gated trades
Parameters:
assets List of asset symbols and target weights (bps)
max_transaction Per-trade cap in TNZO (delegation enforced)
max_daily_spend Daily spend cap in TNZO (delegation enforced)
drift_threshold Minimum drift in bps before rebalancing (default: 100)
allowed_operations Whitelisted operations (default: rebalance, trade)
scope_duration_days Time bound for delegation scope (default: 7)
price_source Price oracle source (default: on-chain)
Identity:
Provisions a machine DID under your controller identity
Auto-provisions MPC wallet with delegation scope
Delegation Scope:
max_transaction_value Configurable (default: 50 TNZO)
max_daily_spend Configurable (default: 200 TNZO)
allowed_operations Configurable
time_bound Configurable (default: 7 days)The Per-Trade Cap is the Real Security Boundary
With max_transaction_value = 50 TNZO and a portfolio total of 200 TNZO, no single rebalance can exceed 25%drift in one shot. If you wanted to allow larger rebalances you'd either bump the cap or split the trade across multiple transactions — but neither happens without a controller signature, which is exactly the property you want.
Step 3: Spawn the Rebalancer Agent
Spawning creates the machine identity under your controller, attaches the delegation scope, and registers the agent on-chain. Pass the asset allocation and caps as flags:
tenzro agent spawn-template ref-yield-rebalancer-v1 \
--param assets='[
{"symbol": "TNZO", "target_bps": 4000},
{"symbol": "USDC", "target_bps": 4000},
{"symbol": "ETH", "target_bps": 2000}
]' \
--param max_transaction=50 \
--param max_daily_spend=200 \
--param drift_threshold=100 \
--param scope_duration_days=7The output confirms everything was provisioned:
Agent spawned successfully
========================
Agent ID: rebalancer-a3f7c2
Agent DID: did:tenzro:machine:<controller-did>:<uuid>
Controller DID: did:tenzro:human:<your-uuid>
Wallet: 0x7a3b...c4e1
Delegation Scope:
max_transaction_value: 50 TNZO
max_daily_spend: 200 TNZO
allowed_operations: rebalance, trade
time_bound: 7 days (expires 2026-04-15)
Target Allocation:
TNZO: 40.00% (4000 bps)
USDC: 40.00% (4000 bps)
ETH: 20.00% (2000 bps)
Drift threshold: 100 bpsYou can verify the identity was registered by resolving the DID:
tenzro identity resolve did:tenzro:machine:<controller-did>:<uuid>Step 4: Dry-Run the Agent
Before committing real trades, run the agent in dry-run mode. This fetches current prices, computes drift against your targets, and shows what trades would be submitted — including delegation enforcement — without touching the chain:
tenzro agent run-template rebalancer-a3f7c2 --dry-runThe dry-run output walks through every asset:
Dry-run: ref-yield-rebalancer-v1 (rebalancer-a3f7c2)
=====================================================
Portfolio value: 200 TNZO
Asset Analysis:
TNZO current: 60.00% (6000 bps) target: 40.00% (4000 bps)
drift: -2000 bps | action: SELL 40 TNZO
delegation check: PASS (40 < 50 max_transaction)
USDC current: 20.00% (2000 bps) target: 40.00% (4000 bps)
drift: +2000 bps | action: BUY 40 TNZO equivalent
delegation check: PASS (40 < 50 max_transaction)
ETH current: 20.00% (2000 bps) target: 20.00% (2000 bps)
drift: 0 bps | action: NONE (on target)
Summary:
trades to execute: 2
total trade value: 80 TNZO
daily spend check: PASS (80 < 200 max_daily_spend)
Oversized trade test:
simulated 250 TNZO trade -> BLOCKED by delegation
(exceeds max_transaction_value of 50 TNZO)
No transactions submitted (dry-run mode).The dry-run confirms three things: drift is computed correctly, each individual trade passes delegation enforcement, and an oversized trade would be blocked. This is the same enforce_operation check that runs during live execution.
Step 5: Live Execution
When the dry-run looks correct, execute for real. Drop the --dry-run flag:
tenzro agent run-template rebalancer-a3f7c2The agent now submits real EVM transactions:
Live run: ref-yield-rebalancer-v1 (rebalancer-a3f7c2)
=====================================================
=== Computing drift ===
TNZO drift: -2000 bps -> SELL
=== Enforcing delegation scope ===
trade value: 40 TNZO -> delegation OK
=== Dispatching EVM transaction ===
tx hash: 0x3a7f...b2c1
gas used: 23,412
status: success
on-chain target weight for TNZO = 4000 bps
---
=== Computing drift ===
USDC drift: +2000 bps -> BUY
=== Enforcing delegation scope ===
trade value: 40 TNZO -> delegation OK
=== Dispatching EVM transaction ===
tx hash: 0x8e2d...f4a9
gas used: 23,412
status: success
on-chain target weight for USDC = 4000 bps
---
ETH drift: 0 bps -> already on target (skipped)
=== Run complete ===
trades executed: 2
total traded: 80 TNZO
trader nonce: 2Step 6: Review Results
After the run, verify the trades landed on-chain. You can check individual transactions by hash or query your wallet's updated balance:
# Check a specific transaction
curl -X POST https://rpc.tenzro.network \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tenzro_getTransaction",
"params": ["0x3a7f...b2c1"],
"id": 1
}'
# Check the agent's wallet balance
tenzro wallet balance
# Verify the agent's identity and delegation scope are still active
tenzro identity resolve <agent-did>You can also query the on-chain state directly to confirm the new target weights were written to the oracle contracts:
# Query block for the trade transactions
curl -X POST https://rpc.tenzro.network \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getTransactionReceipt",
"params": ["0x3a7f...b2c1"],
"id": 1
}'What You Learned
You deployed a complete trading agent without writing any Rust code. The AgentKit template handled three Tenzro subsystems end-to-end:
- TDIP identity — the template provisioned a machine DID under your controller with an auto-provisioned MPC wallet
- Delegation scope — per-tx cap, daily cap, allowed operations, and time bound are all enforced via
enforce_operationbefore every trade - EVM executor — trades are dispatched as real on-chain transactions with calldata-driven storage writes and nonce management
The architecture is the important part: every trade is gated by a real cryptographic delegation scope before it touches the VM. The scope is the security boundary, not the agent code — which is exactly what you want when the agent is going to run unattended.
Customizing the Template
The ref-yield-rebalancer-v1 template supports additional parameters not covered in this tutorial: custom price oracle sources, multi-chain asset targeting, APY threshold evaluation, and automatic bridge + deposit flows. Run tenzro agent get-template ref-yield-rebalancer-v1 --verbose to see the full parameter reference.
Next Steps
- Continue to the Yield Router tutorial to learn how to compose multi-protocol strategies
- Read the DCA Agent tutorial for a time-based version of the same pattern
- See the Multi-VM Commerce Workflows tutorial for the full set of EVM bytecode patterns