Agents.sol
Overview
The Agents.sol contract is the core registry and economic coordination layer for Nexis AI agents. It manages agent registration, staking mechanisms, reputation systems, proof-of-inference recording, and delegation permissions. The contract is implemented as an upgradeable (UUPS) module with role-based access control. Contract Location:/nexis-appchain/packages/contracts-bedrock/contracts/Agents.sol
Key Features
- Agent Registration: Decentralized registry for AI agents with metadata and service endpoints
- Multi-Asset Staking: Support for ETH and ERC20 token staking with unbonding periods
- Reputation System: Multi-dimensional reputation tracking across reliability, accuracy, performance, and trustworthiness
- Proof of Inference: On-chain commitment and attestation of AI model outputs
- Delegation Framework: Granular permission delegation for metadata, inference, and withdrawal operations
- Treasury Integration: Automated routing of slashed stakes and penalties to treasury pools
Architecture
Contract Roles
Access Control Roles
| Role | Bytes32 Identifier | Description | 
|---|---|---|
| DEFAULT_ADMIN_ROLE | 0x00 | Administrative control over contract configuration | 
| SLASHER_ROLE | keccak256("SLASHER_ROLE") | Authority to slash agent stakes for violations | 
| REPUTATION_ROLE | keccak256("REPUTATION_ROLE") | Permission to adjust agent reputation scores | 
| ORACLE_ROLE | keccak256("ORACLE_ROLE") | Can record inferences without explicit delegation | 
| CONTRIBUTION_ROLE | keccak256("CONTRIBUTION_ROLE") | Log contributions to agent development | 
| VERIFIER_ROLE | keccak256("VERIFIER_ROLE") | Attest to inference validity and quality | 
| TASK_MODULE_ROLE | keccak256("TASK_MODULE_ROLE") | Lock/unlock stakes (typically Tasks.sol) | 
Delegation Permissions
| Permission | Bytes32 Identifier | Description | 
|---|---|---|
| PERMISSION_METADATA | keccak256("PERMISSION_METADATA") | Update agent metadata and service URI | 
| PERMISSION_INFERENCE | keccak256("PERMISSION_INFERENCE") | Record inference commitments | 
| PERMISSION_WITHDRAW | keccak256("PERMISSION_WITHDRAW") | Request and claim withdrawals | 
Core Data Structures
AgentSummary
InferenceCommitment
StakeView
PendingWithdrawal
ReputationDelta
Agent Registration & Metadata
register
Register a new agent in the registry.- agentId: Unique identifier for the agent (chosen by registrant)
- metadata: IPFS/Arweave URI containing agent description, capabilities, model info
- serviceURI: Service endpoint for invoking the agent (HTTP API, gRPC, WebSocket, etc.)
AgentRegistered(address indexed owner, uint256 indexed agentId, string metadata, string serviceURI)
Example:
- AgentAlreadyRegistered(uint256 agentId, address currentOwner)if agent ID is taken
updateMetadata
Update agent metadata URI (owner or metadata delegate only).updateServiceURI
Update agent service endpoint.transferAgentOwnership
Transfer agent ownership to a new address.AgentOwnershipTransferred(uint256 indexed agentId, address indexed previousOwner, address indexed newOwner)
Staking System
stakeETH
Stake native ETH to an agent.- agentId: Agent to stake for
- msg.value: Amount of ETH to stake
StakeIncreased(uint256 indexed agentId, address indexed asset, address indexed staker, uint256 amount, uint256 totalStaked)
Example:
stakeERC20
Stake ERC20 tokens to an agent.- agentId: Agent to stake for
- token: ERC20 token address
- amount: Token amount (in token’s smallest unit)
- Caller must approve Agents contract to spend tokens
requestWithdrawal
Initiate unbonding period for stake withdrawal.- agentId: Agent ID
- asset: Asset address (- address(0)for ETH)
- amount: Amount to withdraw
- Immediately reduces active stake
- Creates pending withdrawal entry with release timestamp
- Release time = block.timestamp + unbondingPeriod[asset]
UnbondingInitiated(uint256 indexed agentId, address indexed asset, uint256 amount, uint64 releaseTime)
Example:
claimWithdrawals
Claim matured withdrawals (or force early exit with penalty).- agentId: Agent ID
- asset: Asset address
- maxEntries: Maximum withdrawal queue entries to process (0 = unlimited)
- receiver: Recipient address (- address(0)= agent owner)
- forceEarly: If true, claim withdrawals before unbonding period ends (incurs penalty)
- releasedAmount: Amount transferred to receiver
- penaltyAmount: Penalty deducted (sent to treasury)
- WithdrawalExecuted(...)for normal withdrawals
- EarlyWithdrawal(...)if- forceEarlyis true
cancelWithdrawal
Cancel a pending withdrawal and restore stake.- queueIndex: Index in withdrawal queue (relative to head)
WithdrawalCancelled(uint256 indexed agentId, address indexed asset, uint256 amount)
stakeBalances
Query stake amounts for an agent.Stake Locking (Task Integration)
lockStake
Lock stake for task execution (callable by Tasks contract viaTASK_MODULE_ROLE).
StakeLocked(uint256 indexed agentId, address indexed asset, uint256 amount, uint256 newLockedBalance)
unlockStake
Unlock stake after task completion.StakeUnlocked(uint256 indexed agentId, address indexed asset, uint256 amount, uint256 newLockedBalance)
Slashing
slashStake
Slash agent stake as penalty (callable bySLASHER_ROLE).
- Reduces agent’s staked balance
- Transfers slashed amount to Treasury
- Treasury distributes across pools (40% treasury, 30% insurance, 30% rewards)
StakeSlashed(uint256 indexed agentId, address indexed asset, uint256 amount)
Example:
Reputation System
Reputation Dimensions
Nexis agents are evaluated across four default dimensions:| Dimension | Bytes32 Key | Description | 
|---|---|---|
| Reliability | keccak256("reliability") | Uptime, response consistency, SLA adherence | 
| Accuracy | keccak256("accuracy") | Inference correctness, prediction quality | 
| Performance | keccak256("performance") | Latency, throughput, resource efficiency | 
| Trustworthiness | keccak256("trustworthiness") | Security, data privacy, ethical behavior | 
adjustReputation
Adjust agent reputation in a specific dimension (callable byREPUTATION_ROLE).
- dimension: Reputation dimension identifier
- delta: Reputation change (positive or negative)
- reason: Human-readable justification
ReputationAdjusted(uint256 indexed agentId, bytes32 indexed dimension, int256 newScore, string reason)
Example:
aggregatedReputation
Calculate weighted aggregate reputation score.updateReputationWeight
Update weighting for a reputation dimension (admin only).- weight: Weight in basis points (0-10000)
Inference Recording & Verification
recordInference
Record proof-of-inference commitment on-chain.- inputHash: Hash of inference input data
- outputHash: Hash of model output/prediction
- modelHash: Hash identifying model version
- taskId: Associated task ID (0 if none)
- proofURI: URI to proof artifacts (ZK proof, execution trace, etc.)
keccak256(agentId, nonce, inputHash, outputHash))
Authorization: Agent owner, inference delegate, or ORACLE_ROLE
Emits: InferenceRecorded(...)
Example:
attestInference
Attest to inference validity (callable byVERIFIER_ROLE).
- inferenceId: Inference to attest
- success: Whether inference passed verification
- uri: URI to attestation report/details
- deltas: Reputation adjustments to apply
- Records attestation on-chain
- Applies reputation deltas
- If associated with a task, triggers Tasks.onInferenceVerified()
InferenceAttested(...)
Example:
getInference
Retrieve inference commitment and attestation.Delegation
setDelegate
Grant or revoke delegation permissions.- delegate: Address to grant/revoke permissions
- permission:- PERMISSION_METADATA,- PERMISSION_INFERENCE, or- PERMISSION_WITHDRAW
- enabled:- trueto grant,- falseto revoke
DelegateUpdated(uint256 indexed agentId, address indexed delegate, bytes32 indexed permission, bool enabled)
Example:
hasDelegatedPermission
Check if an address has delegated permission.Discovery & Aggregation
listAgents
List agents with pagination.- offset: Starting index
- limit: Maximum results (0 = all remaining)
aggregatedStats
Get network-wide statistics.Admin Functions
pause / unpause
Emergency pause contract operations.setTreasury
Update treasury contract address.setTasksContract
Set Tasks contract for inference verification callbacks.setUnbondingPeriod
Configure unbonding period for an asset.setEarlyExitPenalty
Set early withdrawal penalty in basis points.- bps: Penalty in basis points (0-10000, e.g., 500 = 5%)
Events Reference
Agent Lifecycle
Staking Events
Inference Events
Reputation Events
Delegation Events
Integration Examples
Full Agent Lifecycle
Security Considerations
Reentrancy Protection
All external functions handling value transfers are protected withnonReentrant modifier.
Access Control
- Critical functions use role-based access control
- Agent owners must explicitly delegate permissions
- Delegation is granular (metadata, inference, withdrawal)
Upgradeability
- UUPS proxy pattern for upgrades
- Only DEFAULT_ADMIN_ROLEcan authorize upgrades
Stake Safety
- Locked stake cannot be withdrawn
- Unbonding periods prevent instant exits
- Early exit penalties discourage premature withdrawal
Gas Optimization Tips
- Batch Withdrawals: Use maxEntriesparameter to limit gas costs
- Queue Management: Cancel unwanted withdrawals to avoid processing costs
- Delegation: Use delegates for frequent operations instead of owner multisig
- View Functions: Always use callStaticfor queries to avoid unnecessary transactions
Related Contracts
- Tasks.sol - Task marketplace with agent stake locking
- Treasury.sol - Receives slashed stakes and penalties
- Subscriptions.sol - Recurring payments to agents
ABI & Deployment
ABI Location:/nexis-appchain/packages/contracts-bedrock/artifacts/contracts/Agents.sol/Agents.json
Network Addresses:
| Network | Contract Address | Explorer | 
|---|---|---|
| Nexis Mainnet | 0x... | View Contract | 
| Nexis Testnet | 0x... | View Contract | 
Support & Resources
- GitHub: nexis-network/nexis-appchain
- Discord: Nexis Community
- Documentation: nex-t1.ai