Validator Onboarding
This guide explains how validators integrate with shMONAD to receive priority fees and MEV rewards.
Overview
By default, priority fees are sent to the beneficiary address a validator sets in their node.toml config file. When onboarded to shMONAD, a coinbase contract is deployed for the validator, which becomes the new destination for both priority fees and MEV rewards.
The Coinbase Contract
When a validator is onboarded to shMONAD:
- A coinbase contract is deployed specifically for that validator
- The validator updates their beneficiary address in
node.tomlto point to this coinbase contract - A restart of
monad-bftis required for the change to take effect
Once configured:
- Priority fees are sent to the coinbase contract
- MEV rewards are also sent to the coinbase contract
MEV rewards will be higher if you run the MEV Sidecar (see below), but rewards can still be received without it if a successful searcher call to the auction handler ends up in one of your blocks.
Configuration Options
The coinbase contract has several configurable parameters. Only the validator's auth address can call the configuration functions.
Default Values
| Parameter | Default Value |
|---|---|
| Priority Fee Commission Rate | Same as staking commission rate |
| MEV Commission Rate | Same as staking commission rate |
| Donation Rate | 0 |
| Commission Recipient | Auth address |
Update Functions
All rate parameters use a scale of 1e18 (so 10% would be 1e17).
| Function | Description |
|---|---|
updatePriorityCommissionRate(uint256) | Update the commission rate for priority fees |
updateMEVCommissionRate(uint256) | Update the commission rate for MEV rewards |
updateShMonadDonationRate(uint256) | Update the donation rate for priority fees |
updateCommissionRecipient(address) | Change where commissions are sent |
updateCommissionRateFromStakingConfig() | Reset both priority fee and MEV commission rates to match the staking commission rate |
updateAuthAddress() | Update auth address when it changes in the staking precompile |
View Functions
| Function | Description |
|---|---|
getPriorityCommissionRate() | Returns the current priority fee commission rate |
getMEVCommissionRate() | Returns the current MEV commission rate |
getCommissionRecipient() | Returns the current commission recipient address |
AUTH_ADDRESS() | Returns the validator's auth address |
Donation Rate
The donation rate is a portion of priority fees only that goes to shMONAD and is counted as revenue. This boosts your validator's stake allocation.
Key points:
- Donation rate + commission rate cannot exceed
1e18(100%) - Donation rate does not apply to MEV rewards (these were already counted as revenue when first received by shMONAD)
Increasing your donation rate can boost your stake allocation, as the donated portion counts toward shMONAD revenue attributed to your validator.
Order of Operations
For new validators joining shMONAD, follow this sequence:
- Get onboarded to shMONAD - A coinbase contract will be deployed for you
- Update beneficiary address - Change your
node.tomlbeneficiary to the coinbase contract address and restartmonad-bft - Run the sidecar - Set up the MEV Sidecar to earn MEV rewards
Following the correct order of operations is important to ensure no funds are lost during the transition.
Coinbase Contract Interface
interface ICoinbase {
// Update functions (only callable by auth address)
function updatePriorityCommissionRate(uint256 newCommissionRate) external;
function updateMEVCommissionRate(uint256 newCommissionRate) external;
function updateShMonadDonationRate(uint256 newDonationRate) external;
function updateCommissionRecipient(address newRecipient) external;
function updateCommissionRateFromStakingConfig() external;
// Auth address update (callable by previous or new auth address)
function updateAuthAddress() external;
// View functions
function getPriorityCommissionRate() external view returns (uint256);
function getMEVCommissionRate() external view returns (uint256);
function getCommissionRecipient() external view returns (address);
function AUTH_ADDRESS() external view returns (address);
// Immutable values
function VAL_ID() external view returns (uint64);
function SHMONAD() external view returns (address);
}
MEV Sidecar
To participate in the FastLane MEV program, validators are required to run the MEV Sidecar on the same machine that is running the validator Monad node. Starting from v0.12.6, monad-bft allows external applications to access the content of its local transaction mempool and to communicate transaction ordering preferences. The MEV Sidecar inspects transactions and scores them according to the MEV they hold.
The MEV Sidecar is provided as a Debian package. This guide assumes a Monad node ≥ v0.12.6 is running and synchronized on the validator's machine, and has been installed following the Monad official instructions.
Installation
Install the latest MEV Sidecar version, v0.0.11.
sudo wget -qO - https://fastlane.xyz/apt/fastlane-apt-key.gpg.bin -O /usr/share/keyrings/fastlane-apt-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/fastlane-apt-keyring.gpg] https://fastlane-apt-repo.s3.amazonaws.com stable main" | sudo tee /etc/apt/sources.list.d/fastlane.list
FASTLANE_HOME=/home/monad/fastlane/
mkdir -p $FASTLANE_HOME
echo -e "NETWORK='testnet'" > $FASTLANE_HOME/.env
echo -e "NETWORK='mainnet'" > $FASTLANE_HOME/.env
sudo apt update && sudo apt install fastlane-sidecar=0.0.11
dpkg -l fastlane-sidecar | grep fastlane-sidecar
Run
sudo systemctl enable fastlane-sidecar
sudo systemctl start fastlane-sidecar
sudo systemctl status fastlane-sidecar
sudo journalctl -fu fastlane-sidecar
Checking the Installation
curl http://localhost:8765/health | jq
last_received_at- Must be a recent timestamp, indicating the sidecar is functioning properlytx_received- Number of transactions the sidecar received from monad-bft. Must be non-zero to be considered healthy
monad-bft gets transactions from the network when the validator is about to become the next leader (as per Monad design), therefore tx_received can show 0 for a few minutes before it starts increasing.
Optional Overrides
The MEV Sidecar works out of the box. This section outlines possible configuration overrides.
Custom Home Directory
Default value is /home/monad/fastlane/. For a custom location, ensure a .env file exists there with the appropriate content (see Installation section) and is accessible by the monad user.
sudo systemctl edit fastlane-sidecar
Add the following in the editor that opens:
[Service]
ExecStart=
ExecStart=/usr/bin/fastlane-sidecar \
--log-level info \
--home </your/custom/path> \
--network "${NETWORK}"
EnvironmentFile=
EnvironmentFile=</your/custom/path/>.env
ReadWritePaths=
ReadWritePaths=</your/custom/path/>
Save and exit, then reload:
sudo systemctl daemon-reload
Custom Health Check Port
The sidecar exposes a health check endpoint on default port 8765. For a custom port:
sudo systemctl edit fastlane-sidecar
Add the following in the editor that opens:
[Service]
ExecStart=
ExecStart=/usr/bin/fastlane-sidecar \
--log-level info \
--network "${NETWORK}" \
--monitoring-port <CUSTOM_PORT>
Save and exit, then reload:
sudo systemctl daemon-reload
CPU Pinning
Each Monad application is assigned a set of CPUs to optimize performance. By default, the MEV Sidecar reuses the CPUs assigned to the monad-rpc application, as it should be doing very little on a validator node.
For validators with more than 16 CPUs available who prefer to isolate the sidecar:
sudo systemctl edit fastlane-sidecar
Add the following in the editor that opens (replace CPU values as needed):
[Service]
AllowedCPUs=16-19
CPUAffinity=16,17,18,19
Save and exit, then reload:
sudo systemctl daemon-reload