Skip to main content

Bonding Mechanism

Overview

The bonding mechanism in shMONAD enables users to lock their shMON tokens within specific policies, creating isolated pools of bonded tokens. This mechanism is fundamental to shMONAD's approach to protocol security and MEV optimization.

Important

Bonding tokens into a policy does not generate additional yield beyond the base staking yield. The bonding mechanism primarily serves protocol security and payment guarantee purposes.

Protocol Security

Bonding plays a crucial role in ensuring Monad's security by:

  • Aligning validator incentives with network health
  • Creating stable, long-term stake commitments
  • Enabling performant and cost-efficient validator operations
  • Supporting a positive feedback loop of work, rewards, and increased stake

MEV Integration

The bonding system integrates with FastLane's MEV infrastructure:

  • Enables validators to participate in productive MEV capture
  • Supports integration with FastLane on Monad node software (MFL)
  • Facilitates MEV yield distribution through policy mechanics
  • Works in conjunction with Atlas EVM for optimized value extraction

Asynchronous Execution Security

Due to Monad's asynchronous execution model, where blocks are built but transaction states are only applied in the subsequent block, the bonding mechanism provides crucial security guarantees:

  • Ensures payment finality for protocols like Atlas
  • Acts as collateral for cross-block transaction guarantees
  • Provides secure state transition during the asynchronous gap
  • Enables protocols to enforce payment obligations across block boundaries

Policy-Driven Architecture

This section explains the bonding process, policy management, and associated operations that enable these features through:

  • Flexible policy creation and management
  • Agent-based operations for advanced functionality
  • Secure token management and holds system
  • Efficient integration with FastLane's infrastructure

Key Concepts

Policies

A policy in shMONAD represents a set of rules and parameters that govern how tokens can be bonded and unbonded. Each policy:

  • Has a unique identifier (policyID)
  • Defines an escrow duration for unbonding
  • Can have multiple authorized agents
  • Maintains separate accounting for bonded and unbonding tokens

Agents

Policy agents are authorized addresses that can:

  • Transfer bonded tokens between accounts
  • Execute sponsored transactions using bonded tokens
  • Manage policy-specific operations

Policy Management

Creating Policies

Administrators can create new policies using:

function createPolicy(
uint48 escrowDuration
) external returns (uint64 policyID, address policyERC20Wrapper);

Parameters:

  • escrowDuration: The mandatory waiting period for unbonding tokens

Returns:

  • policyID: Unique identifier for the policy
  • policyERC20Wrapper: Address of the ERC20 wrapper contract for this policy

Agent Management

// Add a new agent to a policy
function addPolicyAgent(uint64 policyID, address agent) external;

// Remove an agent from a policy
function removePolicyAgent(uint64 policyID, address agent) external;

// Check if an address is a policy agent
function isPolicyAgent(uint64 policyID, address agent) external view returns (bool);

Bonding Operations

Standard Bonding

To bond tokens into a policy:

function bond(
uint64 policyID,
address bondRecipient,
uint256 amount
) external;

Example:

// Approve shMON transfer
shMON.approve(address(shMonad), amountToBond);

// Bond tokens
shMonad.bond(policyID, recipient, amountToBond);

Combined Operations

For efficiency, users can deposit MON and bond in one transaction:

function depositAndBond(
uint64 policyID,
address bondRecipient,
uint256 amountToBond
) external payable;

Automatic Top-Up Mechanism

The Top-Up mechanism automatically maintains a minimum bonded balance for users, ensuring accounts always have sufficient bonded shares available for policy operations.

Key Benefits

  • Operational Continuity: Ensures accounts always have sufficient bonded tokens to cover operations, preventing them from becoming inoperable due to depleted balances
  • User-Controlled Automation: Provides configurable limits on automatic rebonding, with isolated settings per policy for fine-grained control
  • Enhanced User Experience: Reduces manual intervention needs and optimizes gas usage by intelligently managing token balances

Top-Up Configuration

Users can configure their top-up settings using:

function setMinBondedBalance(
uint64 policyID,
uint128 minBonded,
uint128 maxTopUpPerPeriod,
uint32 topUpPeriodDuration
) external;

Parameters:

  • policyID: The policy to set top-up settings for
  • minBonded: Minimum balance to maintain in bonded state
  • maxTopUpPerPeriod: Maximum amount that can be automatically bonded in a period
  • topUpPeriodDuration: Time window controlling top-up frequency (in blocks)
note

Top-up settings are maintained independently for each policy and user combination. This allows users to have different automatic rebonding behaviors across multiple policies based on their specific requirements for each.

How Top-Up Works

  1. Trigger Conditions:

    • When a transaction would cause a user's bonded balance to fall below their set minBonded threshold
    • When an operation requires more bonded funds than a user currently has available
  2. Automatic Process:

    • System calculates how many tokens are needed to restore the minimum balance
    • Transfers required tokens from user's unbonded balance to bonded state
    • Tracks and limits transfers based on user-defined period settings
  3. Rate Limiting:

    • Top-ups are capped by maxTopUpPerPeriod to prevent unexpected large transfers
    • Each period (defined by topUpPeriodDuration) resets the available top-up amount
    • Provides predictable and controlled automatic bonding

Example

// Set up top-up to maintain at least 100 tokens bonded
// Allow up to 50 tokens to be topped up per 7-day period
shMonad.setMinBondedBalance(
policyID, // Target policy
100 * 10**18, // minBonded
50 * 10**18, // maxTopUpPerPeriod
7 days // topUpPeriodDuration (in blocks)
);

Disabling Top-Up

Users can effectively disable the top-up mechanism by setting appropriate parameters:

// Disable top-up by setting minimum values
shMonad.setMinBondedBalance(
policyID,
0, // No minimum
0, // No automatic top-ups
MIN_TOP_UP_PERIOD_DURATION // Required minimum period
);

Integration with Unbonding

When unbonding tokens, users can update their top-up settings through the newMinBalance parameter in the unbond function:

function unbond(
uint64 policyID,
uint256 amount,
uint256 newMinBalance
) external returns (uint256 unbondBlock);

Agent Operations

Bonded Token Transfers

Agents can transfer bonded tokens between accounts:

function agentTransferFromBonded(
uint64 policyID,
address from,
address to,
uint256 amount
) external;

Execute operations using bonded tokens as gas sponsorship:

function agentExecuteWithSponsor(
uint64 policyID,
address account,
address target,
bytes calldata data
) external payable returns (bytes memory);

Security Features

Hold Mechanism

The holds system prevents malicious actions during critical operations:

// Place a hold on bonded tokens
function hold(uint64 policyID, address account, uint256 amount) external;

// Release previously held tokens
function release(uint64 policyID, address account, uint256 amount) external;

View Functions

Monitor policy and account status:

// Get bonded balance
function balanceOfBonded(uint64 policyID, address account) external view returns (uint256);

// Get policy details
function getPolicy(uint64 policyID) external view returns (Policy memory);

// Check hold amount
function getHoldAmount(uint64 policyID, address account) external view returns (uint256);

Integration Examples

Policy Setup and Bonding

// Create a new policy with 7-day escrow
(uint64 policyID, address wrapper) = shMonad.createPolicy(7 days);

// Add an agent
shMonad.addPolicyAgent(policyID, agentAddress);

// Bond tokens
uint256 amount = 1000 * 10**18;
shMonad.bond(policyID, msg.sender, amount);

Agent Operations

// Transfer bonded tokens
shMonad.agentTransferFromBonded(
policyID,
fromAddress,
toAddress,
amount
);

// Execute sponsored transaction
bytes memory result = shMonad.agentExecuteWithSponsor(
policyID,
userAccount,
targetContract,
encodedData
);

Error Handling

Common errors and their solutions:

  1. Insufficient Balance

    error InsufficientBalance(uint256 available, uint256 required);
    • Ensure account has enough unbonded tokens before bonding
    • Check for active holds that might restrict available balance
  2. Invalid Policy

    error InvalidPolicy(uint64 policyID);
    • Verify policy exists and is active
    • Check policy parameters before operations
  3. Unauthorized Agent

    error UnauthorizedAgent(uint64 policyID, address agent);
    • Ensure agent is properly authorized for the policy
    • Verify agent permissions haven't been revoked

Best Practices

  1. Policy Creation

    • Choose appropriate escrow duration based on use case
    • Document policy parameters for users
    • Consider gas costs when setting up policies
  2. Agent Management

    • Implement proper access control for agent operations
    • Regularly audit active agents
    • Use multi-signature for critical agent operations
  3. Bonding Operations

    • Validate balances before bonding
    • Implement proper error handling
    • Consider gas optimization for bulk operations
  4. Top-Up Configuration

    • Set realistic minimum balances based on policy operations
    • Configure periods to match expected usage patterns
    • Regularly monitor and adjust top-up parameters as needed