[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"navigation":3,"\u002Fprotocol\u002Fportal-v2":260,"\u002Fprotocol\u002Fportal-v2-surround":1160},[4,22,105,148,177,186,243],{"title":5,"path":6,"stem":7,"children":8,"page":21},"Agents","\u002Fagents","agents",[9,13,17],{"title":10,"path":11,"stem":12},"LLMs.txt","\u002Fagents\u002Fllms-txt","agents\u002Fllms-txt",{"title":14,"path":15,"stem":16},"MCP Server","\u002Fagents\u002Fmcp-server","agents\u002Fmcp-server",{"title":18,"path":19,"stem":20},"Skills","\u002Fagents\u002Fskills","agents\u002Fskills",false,{"title":23,"path":24,"stem":25,"children":26,"page":21},"Api Reference","\u002Fapi-reference","api-reference",[27,31,35,68],{"title":28,"path":29,"stem":30},"Authentication","\u002Fapi-reference\u002Fauthentication","api-reference\u002Fauthentication",{"title":32,"path":33,"stem":34},"API Reference","\u002Fapi-reference\u002Fintroduction","api-reference\u002Fintroduction",{"title":36,"path":37,"stem":38,"children":39,"page":21},"Orchestration","\u002Fapi-reference\u002Forchestration","api-reference\u002Forchestration",[40,44,48,52,56,60,64],{"title":41,"path":42,"stem":43},"POST \u002Fcancel-order","\u002Fapi-reference\u002Forchestration\u002Fcancel-order","api-reference\u002Forchestration\u002Fcancel-order",{"title":45,"path":46,"stem":47},"GET \u002Forder-status\u002F{orderId}","\u002Fapi-reference\u002Forchestration\u002Forder-status","api-reference\u002Forchestration\u002Forder-status",{"title":49,"path":50,"stem":51},"GET \u002Forders","\u002Fapi-reference\u002Forchestration\u002Forders","api-reference\u002Forchestration\u002Forders",{"title":53,"path":54,"stem":55},"Orchestration API","\u002Fapi-reference\u002Forchestration\u002Foverview","api-reference\u002Forchestration\u002Foverview",{"title":57,"path":58,"stem":59},"POST \u002Fquote","\u002Fapi-reference\u002Forchestration\u002Fquote","api-reference\u002Forchestration\u002Fquote",{"title":61,"path":62,"stem":63},"GET \u002Fsupported-assets","\u002Fapi-reference\u002Forchestration\u002Fsupported-assets","api-reference\u002Forchestration\u002Fsupported-assets",{"title":65,"path":66,"stem":67},"TypeScript Type Generation","\u002Fapi-reference\u002Forchestration\u002Ftype-generation","api-reference\u002Forchestration\u002Ftype-generation",{"title":69,"path":70,"stem":71,"children":72,"page":21},"Recipes","\u002Fapi-reference\u002Frecipes","api-reference\u002Frecipes",[73,77,81,85,89,93,97,101],{"title":74,"path":75,"stem":76},"Collateral Composition","\u002Fapi-reference\u002Frecipes\u002Fcollateral-composition","api-reference\u002Frecipes\u002Fcollateral-composition",{"title":78,"path":79,"stem":80},"Daily Yields","\u002Fapi-reference\u002Frecipes\u002Fdaily-yields","api-reference\u002Frecipes\u002Fdaily-yields",{"title":82,"path":83,"stem":84},"Earner Rate History","\u002Fapi-reference\u002Frecipes\u002Fearner-rate-history","api-reference\u002Frecipes\u002Fearner-rate-history",{"title":86,"path":87,"stem":88},"Minter Daily Expenses","\u002Fapi-reference\u002Frecipes\u002Fminter-daily-expenses","api-reference\u002Frecipes\u002Fminter-daily-expenses",{"title":90,"path":91,"stem":92},"Network Supply","\u002Fapi-reference\u002Frecipes\u002Fnetwork-supply","api-reference\u002Frecipes\u002Fnetwork-supply",{"title":94,"path":95,"stem":96},"Protocol Configuration","\u002Fapi-reference\u002Frecipes\u002Fprotocol-config","api-reference\u002Frecipes\u002Fprotocol-config",{"title":98,"path":99,"stem":100},"Token Holders","\u002Fapi-reference\u002Frecipes\u002Ftoken-holders","api-reference\u002Frecipes\u002Ftoken-holders",{"title":102,"path":103,"stem":104},"Token Overview","\u002Fapi-reference\u002Frecipes\u002Ftoken-overview","api-reference\u002Frecipes\u002Ftoken-overview",{"title":106,"path":107,"stem":108,"children":109,"page":21},"Build","\u002Fbuild","build",[110,114,118,122,126,130,134,138,142,145],{"title":111,"path":112,"stem":113},"Integrating with the M0 Portals","\u002Fbuild\u002Fbridging-developer","build\u002Fbridging-developer",{"title":115,"path":116,"stem":117},"Bridging M And wM Tokens","\u002Fbuild\u002Fbridging-user","build\u002Fbridging-user",{"title":119,"path":120,"stem":121},"Stablecoin Extension Templates","\u002Fbuild\u002Fchoosing-your-model","build\u002Fchoosing-your-model",{"title":123,"path":124,"stem":125},"How to Design Your Stablecoin","\u002Fbuild\u002Foverview","build\u002Foverview",{"title":127,"path":128,"stem":129},"Implementation Guide: NoYield","\u002Fbuild\u002Fsvm-noyield-guide","build\u002Fsvm-noyield-guide",{"title":131,"path":132,"stem":133},"Getting started","\u002Fbuild\u002Fsvm-noyield-guide-overview","build\u002Fsvm-noyield-guide-overview",{"title":135,"path":136,"stem":137},"Implementation Guide: MYieldToOne (Onshore)","\u002Fbuild\u002Ftreasury-guide","build\u002Ftreasury-guide",{"title":139,"path":140,"stem":141},"Implementation Guide: JMI (Offshore)","\u002Fbuild\u002Ftreasury-jmi-guide","build\u002Ftreasury-jmi-guide",{"title":131,"path":143,"stem":144},"\u002Fbuild\u002Ftreasury-jmi-overview","build\u002Ftreasury-jmi-overview",{"title":131,"path":146,"stem":147},"\u002Fbuild\u002Ftreasury-model","build\u002Ftreasury-model",{"title":149,"path":150,"stem":151,"children":152,"page":21},"Get Started","\u002Fget-started","get-started",[153,157,161,165,169,173],{"title":154,"path":155,"stem":156},"Accessing Liquidity","\u002Fget-started\u002Faccessing-liquidity","get-started\u002Faccessing-liquidity",{"title":158,"path":159,"stem":160},"Cross Chain Interoperability","\u002Fget-started\u002Fcross-chain","get-started\u002Fcross-chain",{"title":162,"path":163,"stem":164},"Architecture Overview","\u002Fget-started\u002Fhow-it-works","get-started\u002Fhow-it-works",{"title":166,"path":167,"stem":168},"Overview","\u002Fget-started\u002Foverview","get-started\u002Foverview",{"title":170,"path":171,"stem":172},"Platform Mechanics & Reward Programmability","\u002Fget-started\u002Fprotocol-mechanics","get-started\u002Fprotocol-mechanics",{"title":174,"path":175,"stem":176},"Stablecoin Features","\u002Fget-started\u002Fstablecoin-features","get-started\u002Fstablecoin-features",{"title":178,"path":179,"stem":180,"children":181,"page":21},"Issuers","\u002Fissuers","issuers",[182],{"title":183,"path":184,"stem":185},"Issue Your Stablecoin","\u002Fissuers\u002Foverview","issuers\u002Foverview",{"title":187,"path":188,"stem":189,"children":190,"page":21},"Protocol","\u002Fprotocol","protocol",[191,195,199,203,207,211,215,219,223,227,231,235,239],{"title":192,"path":193,"stem":194},"Distribution Vault","\u002Fprotocol\u002Fdistribution-vault","protocol\u002Fdistribution-vault",{"title":196,"path":197,"stem":198},"M0 Extensions","\u002Fprotocol\u002Fextensions","protocol\u002Fextensions",{"title":200,"path":201,"stem":202},"Limit Order Protocol","\u002Fprotocol\u002Flimit-order-protocol","protocol\u002Flimit-order-protocol",{"title":204,"path":205,"stem":206},"M0 Portals","\u002Fprotocol\u002Fm-portals","protocol\u002Fm-portals",{"title":208,"path":209,"stem":210},"M Token","\u002Fprotocol\u002Fm-token","protocol\u002Fm-token",{"title":212,"path":213,"stem":214},"M Token Specification","\u002Fprotocol\u002Fm-token-spec","protocol\u002Fm-token-spec",{"title":216,"path":217,"stem":218},"Minting & Burning (MinterGateway)","\u002Fprotocol\u002Fminting-burning","protocol\u002Fminting-burning",{"title":220,"path":221,"stem":222},"Portal V2","\u002Fprotocol\u002Fportal-v2","protocol\u002Fportal-v2",{"title":224,"path":225,"stem":226},"Rate Models & Yield","\u002Fprotocol\u002Frate-models","protocol\u002Frate-models",{"title":228,"path":229,"stem":230},"Roles","\u002Fprotocol\u002Froles","protocol\u002Froles",{"title":232,"path":233,"stem":234},"M0 On Solana","\u002Fprotocol\u002Fsolana","protocol\u002Fsolana",{"title":236,"path":237,"stem":238},"Wrapped M (wM)","\u002Fprotocol\u002Fwrapped-m","protocol\u002Fwrapped-m",{"title":240,"path":241,"stem":242},"Wrapped M Specification","\u002Fprotocol\u002Fwrapped-m-spec","protocol\u002Fwrapped-m-spec",{"title":244,"path":245,"stem":246,"children":247,"page":21},"Resources","\u002Fresources","resources",[248,252,256],{"title":249,"path":250,"stem":251},"Deployments","\u002Fresources\u002Faddresses","resources\u002Faddresses",{"title":253,"path":254,"stem":255},"Audits","\u002Fresources\u002Faudits","resources\u002Faudits",{"title":257,"path":258,"stem":259},"Glossary","\u002Fresources\u002Fglossary","resources\u002Fglossary",{"id":261,"title":220,"body":262,"description":1153,"extension":1154,"links":1155,"meta":1156,"navigation":1157,"path":221,"seo":1158,"stem":222,"__hash__":1159},"docs\u002Fprotocol\u002Fportal-v2.md",{"type":263,"value":264,"toc":1123},"minimark",[265,269,273,276,293,298,309,316,343,351,355,362,366,374,406,410,416,442,446,449,464,467,528,535,539,543,588,592,620,624,631,634,653,656,662,665,668,672,681,701,705,712,733,737,747,751,757,783,789,793,796,923,927,930,985,988,1011,1015,1056,1060,1063,1087,1091],[266,267,268],"p",{},"Portal V2 is M0's cross-chain infrastructure for bridging tokens and propagating protocol metadata across multiple blockchains. It replaces the previous dual-implementation model (Portal Standard + Portal Lite) with a unified, modular architecture that supports pluggable bridge adapters.",[270,271,166],"h2",{"id":272},"overview",[266,274,275],{},"Portal V2 serves two core functions in the M0 ecosystem:",[277,278,279,287],"ol",{},[280,281,282,286],"li",{},[283,284,285],"strong",{},"Token Bridging"," - Enables seamless transfer of M0 extension tokens between L1 chains like Ethereum, Solana, and BNB, and supported L2 chains like Arbitrum, Base, and others",[280,288,289,292],{},[283,290,291],{},"Metadata Propagation"," - Synchronizes critical protocol data (earning index, governance registrar values, earner lists) from L1 to all connected L2s. Also supports notification messages when a cross-chain order is filled or cancelled",[294,295,297],"h3",{"id":296},"why-v2","Why V2?",[266,299,300,301,304,305,308],{},"The previous portal system offered two separate implementations: ",[283,302,303],{},"Portal Standard"," (built on Wormhole NTT) and ",[283,306,307],{},"Portal Lite"," (built on Hyperlane). Each was tightly coupled to its underlying bridge provider.",[266,310,311,312,315],{},"Portal V2 introduces a ",[283,313,314],{},"bridge adapter abstraction layer"," that decouples the portal logic from any specific messaging protocol. This enables:",[317,318,319,325,331,337],"ul",{},[280,320,321,324],{},[283,322,323],{},"Multiple bridge providers"," - Both Hyperlane and Wormhole are supported simultaneously, with the ability to add more",[280,326,327,330],{},[283,328,329],{},"Per-chain bridge selection"," - Each destination chain can have a different default bridge adapter",[280,332,333,336],{},[283,334,335],{},"Unified codebase"," - A single Portal implementation replaces two separate codebases",[280,338,339,342],{},[283,340,341],{},"Configurable cross-spoke transfers"," - Spoke-to-spoke transfers can be enabled on a per-chain basis (isolated by default)",[266,344,345,346,350],{},"For background on the previous portal architecture, see ",[347,348,349],"a",{"href":205},"M Portals (V1)",".",[270,352,354],{"id":353},"architecture","Architecture",[266,356,357,358,361],{},"Portal V2 follows a ",[283,359,360],{},"hub-and-spoke model"," with Ethereum as the hub chain.",[294,363,365],{"id":364},"hub-chain-ethereum","Hub Chain (Ethereum)",[266,367,368,369,373],{},"The ",[370,371,372],"code",{},"HubPortal"," contract is deployed on Ethereum - the single source of truth for native issuance and governance. It:",[317,375,376,382,388,394,400],{},[280,377,378,381],{},[283,379,380],{},"Locks"," tokens when bridging to spoke chains",[280,383,384,387],{},[283,385,386],{},"Releases"," locked tokens when bridged back",[280,389,390,393],{},[283,391,392],{},"Tracks bridged principal"," per spoke chain (for isolated spokes) to ensure it never releases more than was locked",[280,395,396,399],{},[283,397,398],{},"Broadcasts"," the earning index, registrar key\u002Fvalue pairs, and earner list updates to spoke chains",[280,401,402,405],{},[283,403,404],{},"Controls earning"," - can enable\u002Fdisable earning for the portal, affecting which index is propagated",[294,407,409],{"id":408},"spoke-chains-l1s-l2s","Spoke Chains (L1s & L2s)",[266,411,412,415],{},[370,413,414],{},"SpokePortal"," contracts are deployed on each supported chain (Optimism, Arbitrum, Base, Solana, and others). They:",[317,417,418,424,430,436],{},[280,419,420,423],{},[283,421,422],{},"Mint"," token representations when tokens are bridged from the hub",[280,425,426,429],{},[283,427,428],{},"Burn"," representations when tokens are bridged back to the hub",[280,431,432,435],{},[283,433,434],{},"Apply"," index and registrar updates received from the hub",[280,437,438,441],{},[283,439,440],{},"Optionally support"," cross-spoke transfers when enabled by the hub",[294,443,445],{"id":444},"bridge-adapter-layer","Bridge Adapter Layer",[266,447,448],{},"Bridge adapters are modular contracts that handle the actual cross-chain message delivery. Each adapter:",[317,450,451,458,461],{},[280,452,453,454,457],{},"Implements a standard ",[370,455,456],{},"IBridgeAdapter"," interface",[280,459,460],{},"Maps internal chain IDs to provider-specific chain IDs",[280,462,463],{},"Handles quoting, sending, and receiving messages",[266,465,466],{},"Current adapters:",[468,469,470,485],"table",{},[471,472,473],"thead",{},[474,475,476,480,482],"tr",{},[477,478,479],"th",{},"Adapter",[477,481,187],{},[477,483,484],{},"Delivery Model",[486,487,488,502,515],"tbody",{},[474,489,490,496,499],{},[491,492,493],"td",{},[370,494,495],{},"HyperlaneBridgeAdapter",[491,497,498],{},"Hyperlane",[491,500,501],{},"Mailbox dispatch with ISM validation",[474,503,504,509,512],{},[491,505,506],{},[370,507,508],{},"WormholeBridgeAdapter",[491,510,511],{},"Wormhole",[491,513,514],{},"Core Bridge publish with Executor-based delivery",[474,516,517,522,525],{},[491,518,519],{},[370,520,521],{},"LayerZeroBridgeAdapter",[491,523,524],{},"LayerZero",[491,526,527],{},"Endpoint dispatch with DVN validation",[266,529,530,531,534],{},"Operators can configure a ",[283,532,533],{},"default adapter"," per destination chain, and users can optionally specify an explicit adapter when sending tokens.",[270,536,538],{"id":537},"token-transfer-flow","Token Transfer Flow",[294,540,542],{"id":541},"hub-to-spoke","Hub to Spoke",[277,544,545,555,558,568,575,578,583],{},[280,546,547,548,551,552,554],{},"User calls ",[370,549,550],{},"sendToken()"," on the ",[370,553,372],{},", specifying amount, destination chain, and recipient",[280,556,557],{},"If sending an extension token, the portal unwraps it first",[280,559,560,561,564,565,567],{},"Tokens are ",[283,562,563],{},"locked"," in the ",[370,566,372],{},"; bridged principal is incremented for the destination spoke",[280,569,570,571,574],{},"A ",[370,572,573],{},"TokenTransfer"," payload is encoded with the amount, current index, and recipient",[280,576,577],{},"The payload is sent via the selected bridge adapter",[280,579,580,581],{},"On the spoke chain, the bridge adapter delivers the message to the ",[370,582,414],{},[280,584,368,585,587],{},[370,586,414],{}," mints tokens to the recipient (wrapping to an extension if specified)",[294,589,591],{"id":590},"spoke-to-hub","Spoke to Hub",[277,593,594,600,606,609,614],{},[280,595,547,596,551,598],{},[370,597,550],{},[370,599,414],{},[280,601,560,602,605],{},[283,603,604],{},"burned"," on the spoke chain",[280,607,608],{},"Message is sent back to the Hub via the bridge adapter",[280,610,368,611,613],{},[370,612,372],{}," verifies that the release amount does not exceed the bridged principal for that spoke",[280,615,560,616,619],{},[283,617,618],{},"released"," (unlocked) and delivered to the recipient on Ethereum",[294,621,623],{"id":622},"spoke-to-spoke","Spoke to Spoke",[266,625,626,627,630],{},"Cross-spoke transfers are ",[283,628,629],{},"disabled by default",". Each spoke starts in isolated mode, where it can only communicate with the hub.",[266,632,633],{},"To enable spoke-to-spoke transfers:",[277,635,636,645],{},[280,637,638,639,551,642,644],{},"The hub operator calls ",[370,640,641],{},"enableCrossSpokeTokenTransfer()",[370,643,372],{}," for the spoke chain",[280,646,647,648,551,650,652],{},"The spoke operator calls ",[370,649,641],{},[370,651,414],{}," for each peer spoke",[266,654,655],{},"Once enabled, tokens are burned on the source spoke and minted on the destination spoke, with a message relayed through the bridge adapter.",[657,658,659],"note",{},[266,660,661],{},"Once cross-spoke transfers are enabled for a spoke, the hub stops tracking\nper-spoke bridged principal for that chain, since tokens can now flow freely\nbetween spokes.",[270,663,291],{"id":664},"metadata-propagation",[266,666,667],{},"Beyond token transfers, Portal V2 propagates critical protocol state from Ethereum to all spoke chains.",[294,669,671],{"id":670},"earning-index","Earning Index",[266,673,368,674,676,677,680],{},[370,675,372],{}," broadcasts the current earning index to spoke chains via ",[370,678,679],{},"sendMTokenIndex()",". Spoke chains use this index to correctly calculate yield accrual.",[317,682,683,692,698],{},[280,684,685,686,551,689,691],{},"When ",[283,687,688],{},"earning is enabled",[370,690,372],{},", the live index from the token contract is used",[280,693,685,694,697],{},[283,695,696],{},"earning is disabled",", a frozen index (captured at disable time) is propagated instead",[280,699,700],{},"Earning can only be enabled once - after being disabled, it cannot be re-enabled",[294,702,704],{"id":703},"registrar-data","Registrar Data",[266,706,707,708,711],{},"Governance parameters from M0's ",[347,709,710],{"href":229},"TTG (Two Token Governance)"," system are propagated to spoke chains:",[317,713,714,724],{},[280,715,716,719,720,723],{},[283,717,718],{},"Key-value pairs"," via ",[370,721,722],{},"sendRegistrarKey()"," - configuration values that govern protocol behavior",[280,725,726,719,729,732],{},[283,727,728],{},"List membership",[370,730,731],{},"sendRegistrarListStatus()"," - whether accounts are on specific governance lists (e.g., approved earners)",[294,734,736],{"id":735},"earner-merkle-roots-svm","Earner Merkle Roots (SVM)",[266,738,739,740,742,743,746],{},"For Solana spoke chains, the ",[370,741,372],{}," can send earner Merkle roots via ",[370,744,745],{},"sendEarnersMerkleRoot()",", enabling Solana-based holders to prove their earner status.",[270,748,750],{"id":749},"orderbook-integration","OrderBook Integration",[266,752,753,754,756],{},"Portal V2 integrates with M0's ",[347,755,200],{"href":201}," to relay cross-chain fill and cancel reports:",[317,758,759,773],{},[280,760,761,764,765,768,769,772],{},[283,762,763],{},"Fill Reports"," - When a solver fills an order on a destination chain, the ",[370,766,767],{},"OrderBook"," calls ",[370,770,771],{},"sendFillReport()"," on the portal to relay the fill details back to the origin chain",[280,774,775,778,779,782],{},[283,776,777],{},"Cancel Reports"," - When an order is cancelled on the destination chain, ",[370,780,781],{},"sendCancelReport()"," relays the cancellation back to the origin chain for refund processing",[266,784,785,786,788],{},"These functions are restricted to the ",[370,787,767],{}," contract address.",[270,790,792],{"id":791},"message-types","Message Types",[266,794,795],{},"All cross-chain messages share a common header and are differentiated by payload type:",[468,797,798,814],{},[471,799,800],{},[474,801,802,805,808,811],{},[477,803,804],{},"Type",[477,806,807],{},"Name",[477,809,810],{},"Direction",[477,812,813],{},"Purpose",[486,815,816,831,847,862,877,892,908],{},[474,817,818,821,825,828],{},[491,819,820],{},"0",[491,822,823],{},[370,824,573],{},[491,826,827],{},"Hub ↔ Spoke, Spoke ↔ Spoke",[491,829,830],{},"Bridge tokens between chains",[474,832,833,836,841,844],{},[491,834,835],{},"1",[491,837,838],{},[370,839,840],{},"Index",[491,842,843],{},"Hub → Spoke",[491,845,846],{},"Broadcast earning index update",[474,848,849,852,857,859],{},[491,850,851],{},"2",[491,853,854],{},[370,855,856],{},"RegistrarKey",[491,858,843],{},[491,860,861],{},"Propagate governance key-value pair",[474,863,864,867,872,874],{},[491,865,866],{},"3",[491,868,869],{},[370,870,871],{},"RegistrarList",[491,873,843],{},[491,875,876],{},"Propagate governance list membership",[474,878,879,882,887,889],{},[491,880,881],{},"4",[491,883,884],{},[370,885,886],{},"FillReport",[491,888,827],{},[491,890,891],{},"Relay OrderBook fill details",[474,893,894,897,902,905],{},[491,895,896],{},"5",[491,898,899],{},[370,900,901],{},"EarnerMerkleRoot",[491,903,904],{},"Hub → Spoke (SVM)",[491,906,907],{},"Broadcast SVM earners merkle root",[474,909,910,913,918,920],{},[491,911,912],{},"6",[491,914,915],{},[370,916,917],{},"CancelReport",[491,919,827],{},[491,921,922],{},"Relay OrderBook cancel details",[270,924,926],{"id":925},"roles-and-permissions","Roles and Permissions",[266,928,929],{},"Portal V2 uses role-based access control:",[468,931,932,942],{},[471,933,934],{},[474,935,936,939],{},[477,937,938],{},"Role",[477,940,941],{},"Capabilities",[486,943,944,959,972],{},[474,945,946,956],{},[491,947,948,951,952,955],{},[283,949,950],{},"Admin"," (",[370,953,954],{},"DEFAULT_ADMIN_ROLE",")",[491,957,958],{},"Authorize contract upgrades",[474,960,961,969],{},[491,962,963,951,966,955],{},[283,964,965],{},"Pauser",[370,967,968],{},"PAUSER_ROLE",[491,970,971],{},"Pause\u002Funpause send and receive operations independently",[474,973,974,982],{},[491,975,976,951,979,955],{},[283,977,978],{},"Operator",[370,980,981],{},"OPERATOR_ROLE",[491,983,984],{},"Configure bridge adapters, bridging paths, gas limits, cross-spoke transfers",[266,986,987],{},"Additionally:",[317,989,990,1001],{},[280,991,992,993,995,996,998,999],{},"Only the ",[283,994,767],{}," contract can call ",[370,997,771],{}," and ",[370,1000,781],{},[280,1002,1003,1004,1007,1008],{},"Only registered ",[283,1005,1006],{},"bridge adapters"," can call ",[370,1009,1010],{},"receiveMessage()",[270,1012,1014],{"id":1013},"security-features","Security Features",[317,1016,1017,1023,1029,1035,1044,1050],{},[280,1018,1019,1022],{},[283,1020,1021],{},"Reentrancy protection"," - Uses transient storage-based locking to prevent recursive calls",[280,1024,1025,1028],{},[283,1026,1027],{},"Message deduplication"," - Each message has a unique ID; processed messages are tracked to prevent replay",[280,1030,1031,1034],{},[283,1032,1033],{},"Independent pause controls"," - Send and receive can be paused separately, allowing partial operation during incidents",[280,1036,1037,1040,1041,1043],{},[283,1038,1039],{},"Per-spoke principal tracking"," - For isolated spokes, the ",[370,1042,372],{}," ensures it never releases more tokens than were locked for that specific spoke",[280,1045,1046,1049],{},[283,1047,1048],{},"Earning freeze"," - The hub can freeze the earning index to manage token supply during transitions",[280,1051,1052,1055],{},[283,1053,1054],{},"Wrap failure fallback"," - If wrapping to an extension fails on the destination, the recipient receives the underlying token instead of the transaction reverting",[270,1057,1059],{"id":1058},"migration-from-v1","Migration from V1",[266,1061,1062],{},"Portal V2 includes migration logic for transitioning from the previous portal system:",[277,1064,1065,1072,1075,1081],{},[280,1066,1067,1068,1071],{},"Storage from V1 is cleaned using dedicated ",[370,1069,1070],{},"StorageCleaner"," contracts",[280,1073,1074],{},"The proxy is upgraded to the V2 implementation",[280,1076,1077,1080],{},[370,1078,1079],{},"migrateBridgedPrincipal()"," is called for each existing spoke to set the correct locked amounts",[280,1082,1083,1086],{},[370,1084,1085],{},"completeMigration()"," finalizes the process, disabling further migration operations",[270,1088,1090],{"id":1089},"related","Related",[317,1092,1093,1098,1103,1108,1114],{},[280,1094,1095,1097],{},[347,1096,154],{"href":155}," - Overview of M0's liquidity infrastructure",[280,1099,1100,1102],{},[347,1101,200],{"href":201}," - Onchain settlement layer for cross-chain swaps",[280,1104,1105,1107],{},[347,1106,349],{"href":205}," - Previous portal architecture reference",[280,1109,1110,1113],{},[347,1111,1112],{"href":159},"Cross-Chain"," - Guide to deploying and bridging stablecoins across networks",[280,1115,1116,1122],{},[347,1117,1121],{"href":1118,"rel":1119},"https:\u002F\u002Fgithub.com\u002Fm0-foundation\u002Fm-portal-v2",[1120],"nofollow","Source Code"," - Smart contract repository",{"title":1124,"searchDepth":1125,"depth":1126,"links":1127},"",1,2,[1128,1132,1137,1142,1147,1148,1149,1150,1151,1152],{"id":272,"depth":1126,"text":166,"children":1129},[1130],{"id":296,"depth":1131,"text":297},3,{"id":353,"depth":1126,"text":354,"children":1133},[1134,1135,1136],{"id":364,"depth":1131,"text":365},{"id":408,"depth":1131,"text":409},{"id":444,"depth":1131,"text":445},{"id":537,"depth":1126,"text":538,"children":1138},[1139,1140,1141],{"id":541,"depth":1131,"text":542},{"id":590,"depth":1131,"text":591},{"id":622,"depth":1131,"text":623},{"id":664,"depth":1126,"text":291,"children":1143},[1144,1145,1146],{"id":670,"depth":1131,"text":671},{"id":703,"depth":1131,"text":704},{"id":735,"depth":1131,"text":736},{"id":749,"depth":1126,"text":750},{"id":791,"depth":1126,"text":792},{"id":925,"depth":1126,"text":926},{"id":1013,"depth":1126,"text":1014},{"id":1058,"depth":1126,"text":1059},{"id":1089,"depth":1126,"text":1090},"Technical deep dive into M0's unified cross-chain bridge and messaging system, featuring modular bridge adapters, token bridging, and protocol metadata propagation.","md",null,{},true,{"title":220,"description":1153},"Yt4WAMrJjOboxzZdbiGWjBz6mbuvtrgk7mzWzSE-Y0Y",[1161,1163],{"title":216,"path":217,"stem":218,"description":1162,"children":-1},"Complete documentation of the MinterGateway contract, the central hub for minting and burning, managing minter collateral, and tracking debt obligations.",{"title":224,"path":225,"stem":226,"description":1164,"children":-1},"Detailed documentation of the interest rate models that govern minter obligations and earner yield within the M0 Protocol."]