The Sudo Policy grants unrestricted access to specified contract functions. It’s the simplest policy—and the most powerful.
When to Use Sudo
Target contract is audited and trusted (Uniswap, Aave, Morpho)
No user funds at direct risk (game actions, governance votes)
You need simplicity over granular control
Combined with time limits or usage limits
When NOT to Use Sudo
Agent handles significant user funds without other limits
Target contract has dangerous functions (e.g., approve for arbitrary spenders)
You need spending caps or parameter validation
Indefinite access without time bounds
Basic Usage
const actions = mcNexus.buildSessionAction({
type: 'transfer',
data: {
chainIds: [10],
contractAddress: UNISWAP_ROUTER,
policies: [{ type: "sudo" }]
}
})
Agent Examples
Yield Optimizer Agent
Trust deposits/withdrawals on vetted protocols:
const TRUSTED_PROTOCOLS = {
morpho: "0xA2Cac0023a4797b4729Db94783405189a4203AFc",
aave: "0x...",
};
const now = Math.floor(Date.now() / 1000)
const validAfter = now
const validUntil = now + 3600
const timeframePolicy = mcNexus.buildActionPolicy({
type: "timeframe",
validAfter, // unix-timestamp when policy becomes active
validUntil // unix-timestamp when policy expires
});
// Morpho deposit
const [actionOne] = mcNexus.buildSessionAction({
type: 'custom',
data: {
chainIds: [10],
contractAddress: TRUSTED_PROTOCOLS.morpho,
functionSignature: toFunctionSelector("deposit(uint256,address)"),
policies: [timeframePolicy]
}
})
// Morpho withdraw
const [actionTwo] = mcNexus.buildSessionAction({
type: 'custom',
data: {
chainIds: [10],
contractAddress: TRUSTED_PROTOCOLS.morpho,
functionSignature: toFunctionSelector("withdraw(uint256,address,address)"),
policies: [timeframePolicy]
}
})
// Aave supply
const [actionThree] = mcNexus.buildSessionAction({
type: 'custom',
data: {
chainIds: [10],
contractAddress: TRUSTED_PROTOCOLS.aave,
functionSignature: toFunctionSelector("supply(address,uint256,address,uint16)"),
policies: [timeframePolicy]
}
})
// Aave withdraw
const [actionFour] = mcNexus.buildSessionAction({
type: 'custom',
data: {
chainIds: [10],
contractAddress: TRUSTED_PROTOCOLS.aave,
functionSignature: toFunctionSelector("withdraw(address,uint256,address)"),
policies: [timeframePolicy]
}
})
const quote = await meeClient.getSessionQuote({
mode: "PREPARE",
enableSession: {
redeemer: agentSigner.address,
actions: [actionOne, actionTwo, actionThree, actionFour],
// Cap gas spend
maxPaymentAmount: parseUnits("50", 6),
},
simulation: { simulate: true },
feeToken: { address: USDC, chainId: 8453 },
// Fund SCA
trigger: {
tokenAddress: USDC,
chainId: 8453,
amount: parseUnits("2", 6),
},
// Any additional Instructions
instructions: [...]
});
// Store the sessions details for later use.
let sessionDetails: SessionDetail[] = [];
if (quote) {
const { hash } = await meeClient.executeSessionQuote(quote);
await meeClient.waitForSupertransactionReceipt({ hash });
if (quote.sessionDetails) sessionDetails = quote.sessionDetails;
}
Gaming Agent
Full access to game contract with usage limits:
const GAME_CONTRACT = "0x...";
const [claimAction] = mcNexus.buildSessionAction({
type: 'custom',
data: {
chainIds: [8453],
contractAddress: GAME_CONTRACT,
functionSignature: toFunctionSelector("claimRewards()"),
policies: [
{
type: "usageLimit",
limit: 100n // Max 100 claims
}
]
}
})
const [performAction] = mcNexus.buildSessionAction({
type: 'custom',
data: {
chainIds: [8453],
contractAddress: GAME_CONTRACT,
functionSignature: toFunctionSelector("performAction(uint256)"),
policies: [
{
type: "usageLimit",
limit: 1000n // Max 1000 actions
}
]
}
})
Governance Agent
Vote on proposals automatically:
const GOVERNOR = "0x...";
const [castVoteAction] = mcNexus.buildSessionAction({
type: 'custom',
data: {
chainIds: [8453],
contractAddress: GOVERNOR,
functionSignature: toFunctionSelector("castVote(uint256,uint8)"),
policies: [
// 1 year for governance
{
type: "timeframe",
validAfter: Math.floor(Date.now() / 1000),
validUntil: Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60
}
]
}
})
Security Checklist
Timeframe Policy configured
Only specific functions allowed (not entire contract)
Target contract is audited
Usage limit considered for high-risk actions
Gas spend capped (maxPaymentAmount)
Common Mistakes
Granting Sudo to approve() functionThis lets the agent approve arbitrary spenders. Never do this:// ❌ DANGEROUS
functionSignature: toFunctionSelector("approve(address,uint256)")
No time limitWithout timeframe policy, the permission never expires:// ❌ BAD - no time limit
const actions = mcNexus.buildSessionAction({
type: 'transfer',
data: {
chainIds: [10],
contractAddress: UNISWAP_ROUTER,
policies: [{ type: "sudo" }]
}
})
// ✅ GOOD - expires in 30 days
const now = Math.floor(Date.now() / 1000)
const validAfter = now
const validUntil = now + 30 * 24 * 60 * 60
const actions = mcNexus.buildSessionAction({
type: 'transfer',
data: {
chainIds: [10],
contractAddress: UNISWAP_ROUTER,
policies: [
{ type: "sudo" },
{
type: "timeframe",
validAfter,
validUntil
}
]
}
})
When to Upgrade to Universal Action
Switch to Universal Action when you need:
- Spending limits (per-action or total)
- Recipient whitelisting
- Parameter validation
- Cumulative caps
See Universal Action Policy for details.