[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"navigation":3,"\u002Fbuild\u002Ftreasury-jmi-guide":260,"\u002Fbuild\u002Ftreasury-jmi-guide-surround":2296},[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":139,"body":262,"description":2290,"extension":2291,"links":2292,"meta":2293,"navigation":530,"path":140,"seo":2294,"stem":141,"__hash__":2295},"docs\u002Fbuild\u002Ftreasury-jmi-guide.md",{"type":263,"value":264,"toc":2276},"minimark",[265,272,275,286,297,302,310,315,322,491,495,509,705,710,790,804,808,815,1045,1049,1052,1396,1400,1403,1460,1466,1470,1473,1499,1506,1510,1513,1524,1528,1532,1591,1595,1643,1647,1650,1694,1698,1701,1710,1714,1718,1761,1765,1822,1826,1855,1859,1874,1878,1932,1936,1956,1960,2101,2105,2109,2190,2194,2266,2272],[266,267,268],"note",{},[269,270,271],"p",{},"The JMI extension is currently available on EVM chains only (Ethereum, Base, Arbitrum, etc.).",[269,273,274],{},"This guide provides step-by-step instructions for deploying a JMI (Just Mint It) extension, where multiple collateral types are accepted and 100% of the rewards are captured by a designated recipient.",[269,276,277,278,285],{},"If you haven't already, please review the ",[279,280,281],"a",{"href":143},[282,283,284],"strong",{},"JMI Deep Dive"," for conceptual details about this model.",[266,287,288],{},[269,289,290,291,296],{},"For single-collateral deployments, consider the simpler ",[279,292,293],{"href":136},[282,294,295],{},"MYieldToOne implementation"," instead.",[298,299,301],"h2",{"id":300},"evm-implementation","EVM Implementation",[269,303,304,305,309],{},"This section covers deploying the ",[306,307,308],"code",{},"JMIExtension"," contract on EVM chains (Ethereum, Base, Arbitrum, etc.).",[311,312,314],"h3",{"id":313},"_1-setup-your-environment","1. Setup Your Environment",[269,316,317,318,321],{},"First, clone the ",[306,319,320],{},"m-extensions"," repository and set up your development environment:",[323,324,325,366,381],"ol",{},[326,327,328,331],"li",{},[282,329,330],{},"Clone the repository:",[332,333,338],"pre",{"className":334,"code":335,"language":336,"meta":337,"style":337},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","git clone https:\u002F\u002Fgithub.com\u002Fm0-foundation\u002Fm-extensions.git\ncd m-extensions\n","bash","",[306,339,340,356],{"__ignoreMap":337},[341,342,345,349,353],"span",{"class":343,"line":344},"line",1,[341,346,348],{"class":347},"sBMFI","git",[341,350,352],{"class":351},"sfazB"," clone",[341,354,355],{"class":351}," https:\u002F\u002Fgithub.com\u002Fm0-foundation\u002Fm-extensions.git\n",[341,357,359,363],{"class":343,"line":358},2,[341,360,362],{"class":361},"s2Zo4","cd",[341,364,365],{"class":351}," m-extensions\n",[326,367,368,371,372,380],{},[282,369,370],{},"Follow the setup instructions:"," Refer to the ",[279,373,377],{"href":374,"rel":375},"https:\u002F\u002Fgithub.com\u002Fm0-foundation\u002Fm-extensions\u002Fblob\u002Fmain\u002FREADME.md",[376],"nofollow",[282,378,379],{},"README.md"," and follow all commands to install dependencies and configure your development environment.",[326,382,383,386,387,390,391,460,463,464,466,467],{},[282,384,385],{},"Configure Environment Variables:"," Create a ",[306,388,389],{},".env"," file in the root directory:\n",[332,392,394],{"className":334,"code":393,"language":336,"meta":337,"style":337},"# Private key for deployment (include 0x prefix)\nPRIVATE_KEY=0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\n# RPC URLs\nMAINNET_RPC_URL=https:\u002F\u002Feth-mainnet.alchemyapi.io\u002Fv2\u002Fyour-api-key\nSEPOLIA_RPC_URL=https:\u002F\u002Feth-sepolia.alchemyapi.io\u002Fv2\u002Fyour-api-key\n# Etherscan API key for verification\nETHERSCAN_API_KEY=your-etherscan-api-key\n",[306,395,396,402,415,421,432,443,449],{"__ignoreMap":337},[341,397,398],{"class":343,"line":344},[341,399,401],{"class":400},"sHwdD","# Private key for deployment (include 0x prefix)\n",[341,403,404,408,412],{"class":343,"line":358},[341,405,407],{"class":406},"sTEyZ","PRIVATE_KEY",[341,409,411],{"class":410},"sMK4o","=",[341,413,414],{"class":351},"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef\n",[341,416,418],{"class":343,"line":417},3,[341,419,420],{"class":400},"# RPC URLs\n",[341,422,424,427,429],{"class":343,"line":423},4,[341,425,426],{"class":406},"MAINNET_RPC_URL",[341,428,411],{"class":410},[341,430,431],{"class":351},"https:\u002F\u002Feth-mainnet.alchemyapi.io\u002Fv2\u002Fyour-api-key\n",[341,433,435,438,440],{"class":343,"line":434},5,[341,436,437],{"class":406},"SEPOLIA_RPC_URL",[341,439,411],{"class":410},[341,441,442],{"class":351},"https:\u002F\u002Feth-sepolia.alchemyapi.io\u002Fv2\u002Fyour-api-key\n",[341,444,446],{"class":343,"line":445},6,[341,447,448],{"class":400},"# Etherscan API key for verification\n",[341,450,452,455,457],{"class":343,"line":451},7,[341,453,454],{"class":406},"ETHERSCAN_API_KEY",[341,456,411],{"class":410},[341,458,459],{"class":351},"your-etherscan-api-key\n",[282,461,462],{},"Security Warning:"," Never commit your ",[306,465,389],{}," file to version control:\n",[332,468,470],{"className":334,"code":469,"language":336,"meta":337,"style":337},"echo \".env\" >> .gitignore\n",[306,471,472],{"__ignoreMap":337},[341,473,474,477,480,482,485,488],{"class":343,"line":344},[341,475,476],{"class":361},"echo",[341,478,479],{"class":410}," \"",[341,481,389],{"class":351},[341,483,484],{"class":410},"\"",[341,486,487],{"class":410}," >>",[341,489,490],{"class":351}," .gitignore\n",[311,492,494],{"id":493},"_2-create-your-contract","2. Create Your Contract",[269,496,497,498,500,501,504,505,508],{},"Your custom JMI extension will inherit from ",[306,499,308],{},". Create a new file in the ",[306,502,503],{},"src\u002F"," directory, for example, ",[306,506,507],{},"MyJMIToken.sol",":",[332,510,514],{"className":511,"code":512,"language":513,"meta":337,"style":337},"language-solidity shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.26;\n\nimport { JMIExtension } from \".\u002Fprojects\u002Fjmi\u002FJMIExtension.sol\";\n\ncontract MyJMIToken is JMIExtension {\n    \u002F\u002F\u002F @custom:oz-upgrades-unsafe-allow constructor\n    constructor(address mToken_, address swapFacility_) JMIExtension(mToken_, swapFacility_) {\n        _disableInitializers();\n    }\n\n    function initialize(\n        string memory name,\n        string memory symbol,\n        address yieldRecipient_,\n        address admin,\n        address assetCapManager,\n        address freezeManager,\n        address pauser,\n        address yieldRecipientManager\n    ) public override initializer {\n        JMIExtension.initialize(\n            name,                    \u002F\u002F \"My JMI USD\"\n            symbol,                  \u002F\u002F \"jUSD\"\n            yieldRecipient_,         \u002F\u002F Treasury wallet address\n            admin,                   \u002F\u002F Admin multisig address\n            assetCapManager,         \u002F\u002F Asset cap manager address\n            freezeManager,           \u002F\u002F Freeze manager address\n            pauser,                  \u002F\u002F Pauser address\n            yieldRecipientManager    \u002F\u002F Rewards recipient manager address\n        );\n    }\n}\n","solidity",[306,515,516,521,526,532,537,541,546,551,557,563,569,574,580,586,592,598,604,610,616,622,628,634,640,646,652,658,664,670,676,682,688,694,699],{"__ignoreMap":337},[341,517,518],{"class":343,"line":344},[341,519,520],{},"\u002F\u002F SPDX-License-Identifier: BUSL-1.1\n",[341,522,523],{"class":343,"line":358},[341,524,525],{},"pragma solidity 0.8.26;\n",[341,527,528],{"class":343,"line":417},[341,529,531],{"emptyLinePlaceholder":530},true,"\n",[341,533,534],{"class":343,"line":423},[341,535,536],{},"import { JMIExtension } from \".\u002Fprojects\u002Fjmi\u002FJMIExtension.sol\";\n",[341,538,539],{"class":343,"line":434},[341,540,531],{"emptyLinePlaceholder":530},[341,542,543],{"class":343,"line":445},[341,544,545],{},"contract MyJMIToken is JMIExtension {\n",[341,547,548],{"class":343,"line":451},[341,549,550],{},"    \u002F\u002F\u002F @custom:oz-upgrades-unsafe-allow constructor\n",[341,552,554],{"class":343,"line":553},8,[341,555,556],{},"    constructor(address mToken_, address swapFacility_) JMIExtension(mToken_, swapFacility_) {\n",[341,558,560],{"class":343,"line":559},9,[341,561,562],{},"        _disableInitializers();\n",[341,564,566],{"class":343,"line":565},10,[341,567,568],{},"    }\n",[341,570,572],{"class":343,"line":571},11,[341,573,531],{"emptyLinePlaceholder":530},[341,575,577],{"class":343,"line":576},12,[341,578,579],{},"    function initialize(\n",[341,581,583],{"class":343,"line":582},13,[341,584,585],{},"        string memory name,\n",[341,587,589],{"class":343,"line":588},14,[341,590,591],{},"        string memory symbol,\n",[341,593,595],{"class":343,"line":594},15,[341,596,597],{},"        address yieldRecipient_,\n",[341,599,601],{"class":343,"line":600},16,[341,602,603],{},"        address admin,\n",[341,605,607],{"class":343,"line":606},17,[341,608,609],{},"        address assetCapManager,\n",[341,611,613],{"class":343,"line":612},18,[341,614,615],{},"        address freezeManager,\n",[341,617,619],{"class":343,"line":618},19,[341,620,621],{},"        address pauser,\n",[341,623,625],{"class":343,"line":624},20,[341,626,627],{},"        address yieldRecipientManager\n",[341,629,631],{"class":343,"line":630},21,[341,632,633],{},"    ) public override initializer {\n",[341,635,637],{"class":343,"line":636},22,[341,638,639],{},"        JMIExtension.initialize(\n",[341,641,643],{"class":343,"line":642},23,[341,644,645],{},"            name,                    \u002F\u002F \"My JMI USD\"\n",[341,647,649],{"class":343,"line":648},24,[341,650,651],{},"            symbol,                  \u002F\u002F \"jUSD\"\n",[341,653,655],{"class":343,"line":654},25,[341,656,657],{},"            yieldRecipient_,         \u002F\u002F Treasury wallet address\n",[341,659,661],{"class":343,"line":660},26,[341,662,663],{},"            admin,                   \u002F\u002F Admin multisig address\n",[341,665,667],{"class":343,"line":666},27,[341,668,669],{},"            assetCapManager,         \u002F\u002F Asset cap manager address\n",[341,671,673],{"class":343,"line":672},28,[341,674,675],{},"            freezeManager,           \u002F\u002F Freeze manager address\n",[341,677,679],{"class":343,"line":678},29,[341,680,681],{},"            pauser,                  \u002F\u002F Pauser address\n",[341,683,685],{"class":343,"line":684},30,[341,686,687],{},"            yieldRecipientManager    \u002F\u002F Rewards recipient manager address\n",[341,689,691],{"class":343,"line":690},31,[341,692,693],{},"        );\n",[341,695,697],{"class":343,"line":696},32,[341,698,568],{},[341,700,702],{"class":343,"line":701},33,[341,703,704],{},"}\n",[706,707,709],"h4",{"id":708},"key-parameters-explained","Key Parameters Explained",[711,712,713,721,729,735,747,758,769,780],"ul",{},[326,714,715,720],{},[282,716,717],{},[306,718,719],{},"name",": The full name of your token (e.g., \"My JMI USD\")",[326,722,723,728],{},[282,724,725],{},[306,726,727],{},"symbol",": The token symbol (e.g., \"jUSD\")",[326,730,731,734],{},[306,732,733],{},"yieldRecipient_",": The wallet receiving all rewards (your treasury)",[326,736,737,742,743,746],{},[282,738,739],{},[306,740,741],{},"admin",": Address with ",[306,744,745],{},"DEFAULT_ADMIN_ROLE"," (should be a multisig)",[326,748,749,742,754,757],{},[282,750,751],{},[306,752,753],{},"assetCapManager",[306,755,756],{},"ASSET_CAP_MANAGER_ROLE"," (manages collateral caps)",[326,759,760,742,765,768],{},[282,761,762],{},[306,763,764],{},"freezeManager",[306,766,767],{},"FREEZE_MANAGER_ROLE"," (can freeze addresses)",[326,770,771,742,776,779],{},[282,772,773],{},[306,774,775],{},"pauser",[306,777,778],{},"PAUSER_ROLE"," (emergency stop)",[326,781,782,742,787],{},[282,783,784],{},[306,785,786],{},"yieldRecipientManager",[306,788,789],{},"YIELD_RECIPIENT_MANAGER_ROLE",[269,791,792,795,796,799,800,803],{},[282,793,794],{},"Note:"," The ",[306,797,798],{},"mToken"," and ",[306,801,802],{},"swapFacility"," addresses are set in the constructor as immutable variables.",[311,805,807],{"id":806},"_3-write-deployment-script","3. Write Deployment Script",[269,809,810,811,814],{},"Create a deployment script in the ",[306,812,813],{},"script\u002F"," directory:",[332,816,818],{"className":511,"code":817,"language":513,"meta":337,"style":337},"\u002F\u002F SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.26;\n\nimport { Script, console } from \"forge-std\u002FScript.sol\";\nimport { Upgrades } from \"openzeppelin-foundry-upgrades\u002FUpgrades.sol\";\nimport { MyJMIToken } from \"..\u002Fsrc\u002FMyJMIToken.sol\";\n\ncontract DeployMyJMIToken is Script {\n    function run() external {\n        uint256 deployerPrivateKey = vm.envUint(\"PRIVATE_KEY\");\n        address deployer = vm.addr(deployerPrivateKey);\n\n        \u002F\u002F Configuration - update these addresses for your deployment\n        address mToken = 0x...; \u002F\u002F M Token address for your chain\n        address swapFacility = 0x...; \u002F\u002F SwapFacility address for your chain\n\n        vm.startBroadcast(deployerPrivateKey);\n\n        address proxy = Upgrades.deployTransparentProxy(\n            \"MyJMIToken.sol\",\n            deployer,\n            abi.encodeCall(\n                MyJMIToken.initialize,\n                (\n                    \"My JMI USD\",           \u002F\u002F name\n                    \"jUSD\",                 \u002F\u002F symbol\n                    0x...,                  \u002F\u002F rewards recipient\n                    0x...,                  \u002F\u002F admin\n                    0x...,                  \u002F\u002F assetCapManager\n                    0x...,                  \u002F\u002F freezeManager\n                    0x...,                  \u002F\u002F pauser\n                    0x...                   \u002F\u002F rewards recipient manager\n                )\n            ),\n            Upgrades.DeployOptions({\n                constructorData: abi.encode(mToken, swapFacility)\n            })\n        );\n\n        vm.stopBroadcast();\n\n        console.log(\"MyJMIToken deployed at:\", proxy);\n    }\n}\n",[306,819,820,824,828,832,837,842,847,851,856,861,866,871,875,880,885,890,894,899,903,908,913,918,923,928,933,941,949,954,959,964,969,974,979,984,990,996,1002,1008,1013,1018,1024,1029,1035,1040],{"__ignoreMap":337},[341,821,822],{"class":343,"line":344},[341,823,520],{},[341,825,826],{"class":343,"line":358},[341,827,525],{},[341,829,830],{"class":343,"line":417},[341,831,531],{"emptyLinePlaceholder":530},[341,833,834],{"class":343,"line":423},[341,835,836],{},"import { Script, console } from \"forge-std\u002FScript.sol\";\n",[341,838,839],{"class":343,"line":434},[341,840,841],{},"import { Upgrades } from \"openzeppelin-foundry-upgrades\u002FUpgrades.sol\";\n",[341,843,844],{"class":343,"line":445},[341,845,846],{},"import { MyJMIToken } from \"..\u002Fsrc\u002FMyJMIToken.sol\";\n",[341,848,849],{"class":343,"line":451},[341,850,531],{"emptyLinePlaceholder":530},[341,852,853],{"class":343,"line":553},[341,854,855],{},"contract DeployMyJMIToken is Script {\n",[341,857,858],{"class":343,"line":559},[341,859,860],{},"    function run() external {\n",[341,862,863],{"class":343,"line":565},[341,864,865],{},"        uint256 deployerPrivateKey = vm.envUint(\"PRIVATE_KEY\");\n",[341,867,868],{"class":343,"line":571},[341,869,870],{},"        address deployer = vm.addr(deployerPrivateKey);\n",[341,872,873],{"class":343,"line":576},[341,874,531],{"emptyLinePlaceholder":530},[341,876,877],{"class":343,"line":582},[341,878,879],{},"        \u002F\u002F Configuration - update these addresses for your deployment\n",[341,881,882],{"class":343,"line":588},[341,883,884],{},"        address mToken = 0x...; \u002F\u002F M Token address for your chain\n",[341,886,887],{"class":343,"line":594},[341,888,889],{},"        address swapFacility = 0x...; \u002F\u002F SwapFacility address for your chain\n",[341,891,892],{"class":343,"line":600},[341,893,531],{"emptyLinePlaceholder":530},[341,895,896],{"class":343,"line":606},[341,897,898],{},"        vm.startBroadcast(deployerPrivateKey);\n",[341,900,901],{"class":343,"line":612},[341,902,531],{"emptyLinePlaceholder":530},[341,904,905],{"class":343,"line":618},[341,906,907],{},"        address proxy = Upgrades.deployTransparentProxy(\n",[341,909,910],{"class":343,"line":624},[341,911,912],{},"            \"MyJMIToken.sol\",\n",[341,914,915],{"class":343,"line":630},[341,916,917],{},"            deployer,\n",[341,919,920],{"class":343,"line":636},[341,921,922],{},"            abi.encodeCall(\n",[341,924,925],{"class":343,"line":642},[341,926,927],{},"                MyJMIToken.initialize,\n",[341,929,930],{"class":343,"line":648},[341,931,932],{},"                (\n",[341,934,935,938],{"class":343,"line":654},[341,936,937],{},"                    \"My JMI USD\",",[341,939,940],{},"           \u002F\u002F name\n",[341,942,943,946],{"class":343,"line":660},[341,944,945],{},"                    \"jUSD\",",[341,947,948],{},"                 \u002F\u002F symbol\n",[341,950,951],{"class":343,"line":666},[341,952,953],{},"                    0x...,                  \u002F\u002F rewards recipient\n",[341,955,956],{"class":343,"line":672},[341,957,958],{},"                    0x...,                  \u002F\u002F admin\n",[341,960,961],{"class":343,"line":678},[341,962,963],{},"                    0x...,                  \u002F\u002F assetCapManager\n",[341,965,966],{"class":343,"line":684},[341,967,968],{},"                    0x...,                  \u002F\u002F freezeManager\n",[341,970,971],{"class":343,"line":690},[341,972,973],{},"                    0x...,                  \u002F\u002F pauser\n",[341,975,976],{"class":343,"line":696},[341,977,978],{},"                    0x...                   \u002F\u002F rewards recipient manager\n",[341,980,981],{"class":343,"line":701},[341,982,983],{},"                )\n",[341,985,987],{"class":343,"line":986},34,[341,988,989],{},"            ),\n",[341,991,993],{"class":343,"line":992},35,[341,994,995],{},"            Upgrades.DeployOptions({\n",[341,997,999],{"class":343,"line":998},36,[341,1000,1001],{},"                constructorData: abi.encode(mToken, swapFacility)\n",[341,1003,1005],{"class":343,"line":1004},37,[341,1006,1007],{},"            })\n",[341,1009,1011],{"class":343,"line":1010},38,[341,1012,693],{},[341,1014,1016],{"class":343,"line":1015},39,[341,1017,531],{"emptyLinePlaceholder":530},[341,1019,1021],{"class":343,"line":1020},40,[341,1022,1023],{},"        vm.stopBroadcast();\n",[341,1025,1027],{"class":343,"line":1026},41,[341,1028,531],{"emptyLinePlaceholder":530},[341,1030,1032],{"class":343,"line":1031},42,[341,1033,1034],{},"        console.log(\"MyJMIToken deployed at:\", proxy);\n",[341,1036,1038],{"class":343,"line":1037},43,[341,1039,568],{},[341,1041,1043],{"class":343,"line":1042},44,[341,1044,704],{},[311,1046,1048],{"id":1047},"_4-testing-your-contract","4. Testing Your Contract",[269,1050,1051],{},"Create comprehensive tests before deployment:",[332,1053,1055],{"className":511,"code":1054,"language":513,"meta":337,"style":337},"\u002F\u002F SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.26;\n\nimport { Test } from \"forge-std\u002FTest.sol\";\nimport { MyJMIToken } from \"..\u002Fsrc\u002FMyJMIToken.sol\";\nimport { IERC20 } from \"openzeppelin-contracts\u002Ftoken\u002FERC20\u002FIERC20.sol\";\n\ncontract MyJMITokenTest is Test {\n    MyJMIToken token;\n\n    address admin = makeAddr(\"admin\");\n    address assetCapManager = makeAddr(\"assetCapManager\");\n    address treasury = makeAddr(\"treasury\");\n    address user = makeAddr(\"user\");\n\n    address mockUSDC;\n    address mockDAI;\n\n    function setUp() public {\n        \u002F\u002F Deploy mock tokens\n        \u002F\u002F Deploy your JMI token\n        \u002F\u002F Initialize with test addresses\n    }\n\n    function testSetAssetCap() public {\n        uint256 usdcCap = 1_000_000e6; \u002F\u002F 1M USDC\n\n        vm.prank(assetCapManager);\n        token.setAssetCap(mockUSDC, usdcCap);\n\n        assertEq(token.assetCap(mockUSDC), usdcCap);\n        assertTrue(token.isAllowedAsset(mockUSDC));\n    }\n\n    function testWrapWithUSDC() public {\n        \u002F\u002F Setup: Set cap and mint USDC to swap facility\n        uint256 amount = 1000e6;\n\n        \u002F\u002F Test wrapping USDC through SwapFacility\n        \u002F\u002F Assert JMI tokens minted\n        \u002F\u002F Assert totalAssets increased\n    }\n\n    function testUnwrapLimitedToMBacking() public {\n        \u002F\u002F Setup: Wrap some M and some USDC\n        \u002F\u002F Try to unwrap more than M backing\n        \u002F\u002F Expect revert with InsufficientMBacking\n    }\n\n    function testReplaceAssetWithM() public {\n        \u002F\u002F Setup: Have USDC in the contract\n        \u002F\u002F Call replaceAssetWithM to swap M for USDC\n        \u002F\u002F Assert totalAssets decreased\n        \u002F\u002F Assert USDC sent to recipient\n    }\n\n    function testFreezing() public {\n        vm.prank(admin); \u002F\u002F Assuming admin has freeze manager role\n        token.freeze(user);\n        assertTrue(token.isFrozen(user));\n    }\n\n    function testYieldClaim() public {\n        \u002F\u002F Setup: Wrap M and let rewards accrue\n        \u002F\u002F Call claimYield\n        \u002F\u002F Assert rewards went to treasury\n    }\n}\n",[306,1056,1057,1061,1065,1069,1074,1078,1083,1087,1092,1097,1101,1106,1111,1116,1121,1125,1130,1135,1139,1144,1149,1154,1159,1163,1167,1172,1177,1181,1186,1191,1195,1200,1205,1209,1213,1218,1223,1228,1232,1237,1242,1247,1251,1255,1260,1266,1272,1278,1283,1288,1294,1300,1306,1312,1318,1323,1328,1334,1340,1346,1352,1357,1362,1368,1374,1380,1386,1391],{"__ignoreMap":337},[341,1058,1059],{"class":343,"line":344},[341,1060,520],{},[341,1062,1063],{"class":343,"line":358},[341,1064,525],{},[341,1066,1067],{"class":343,"line":417},[341,1068,531],{"emptyLinePlaceholder":530},[341,1070,1071],{"class":343,"line":423},[341,1072,1073],{},"import { Test } from \"forge-std\u002FTest.sol\";\n",[341,1075,1076],{"class":343,"line":434},[341,1077,846],{},[341,1079,1080],{"class":343,"line":445},[341,1081,1082],{},"import { IERC20 } from \"openzeppelin-contracts\u002Ftoken\u002FERC20\u002FIERC20.sol\";\n",[341,1084,1085],{"class":343,"line":451},[341,1086,531],{"emptyLinePlaceholder":530},[341,1088,1089],{"class":343,"line":553},[341,1090,1091],{},"contract MyJMITokenTest is Test {\n",[341,1093,1094],{"class":343,"line":559},[341,1095,1096],{},"    MyJMIToken token;\n",[341,1098,1099],{"class":343,"line":565},[341,1100,531],{"emptyLinePlaceholder":530},[341,1102,1103],{"class":343,"line":571},[341,1104,1105],{},"    address admin = makeAddr(\"admin\");\n",[341,1107,1108],{"class":343,"line":576},[341,1109,1110],{},"    address assetCapManager = makeAddr(\"assetCapManager\");\n",[341,1112,1113],{"class":343,"line":582},[341,1114,1115],{},"    address treasury = makeAddr(\"treasury\");\n",[341,1117,1118],{"class":343,"line":588},[341,1119,1120],{},"    address user = makeAddr(\"user\");\n",[341,1122,1123],{"class":343,"line":594},[341,1124,531],{"emptyLinePlaceholder":530},[341,1126,1127],{"class":343,"line":600},[341,1128,1129],{},"    address mockUSDC;\n",[341,1131,1132],{"class":343,"line":606},[341,1133,1134],{},"    address mockDAI;\n",[341,1136,1137],{"class":343,"line":612},[341,1138,531],{"emptyLinePlaceholder":530},[341,1140,1141],{"class":343,"line":618},[341,1142,1143],{},"    function setUp() public {\n",[341,1145,1146],{"class":343,"line":624},[341,1147,1148],{},"        \u002F\u002F Deploy mock tokens\n",[341,1150,1151],{"class":343,"line":630},[341,1152,1153],{},"        \u002F\u002F Deploy your JMI token\n",[341,1155,1156],{"class":343,"line":636},[341,1157,1158],{},"        \u002F\u002F Initialize with test addresses\n",[341,1160,1161],{"class":343,"line":642},[341,1162,568],{},[341,1164,1165],{"class":343,"line":648},[341,1166,531],{"emptyLinePlaceholder":530},[341,1168,1169],{"class":343,"line":654},[341,1170,1171],{},"    function testSetAssetCap() public {\n",[341,1173,1174],{"class":343,"line":660},[341,1175,1176],{},"        uint256 usdcCap = 1_000_000e6; \u002F\u002F 1M USDC\n",[341,1178,1179],{"class":343,"line":666},[341,1180,531],{"emptyLinePlaceholder":530},[341,1182,1183],{"class":343,"line":672},[341,1184,1185],{},"        vm.prank(assetCapManager);\n",[341,1187,1188],{"class":343,"line":678},[341,1189,1190],{},"        token.setAssetCap(mockUSDC, usdcCap);\n",[341,1192,1193],{"class":343,"line":684},[341,1194,531],{"emptyLinePlaceholder":530},[341,1196,1197],{"class":343,"line":690},[341,1198,1199],{},"        assertEq(token.assetCap(mockUSDC), usdcCap);\n",[341,1201,1202],{"class":343,"line":696},[341,1203,1204],{},"        assertTrue(token.isAllowedAsset(mockUSDC));\n",[341,1206,1207],{"class":343,"line":701},[341,1208,568],{},[341,1210,1211],{"class":343,"line":986},[341,1212,531],{"emptyLinePlaceholder":530},[341,1214,1215],{"class":343,"line":992},[341,1216,1217],{},"    function testWrapWithUSDC() public {\n",[341,1219,1220],{"class":343,"line":998},[341,1221,1222],{},"        \u002F\u002F Setup: Set cap and mint USDC to swap facility\n",[341,1224,1225],{"class":343,"line":1004},[341,1226,1227],{},"        uint256 amount = 1000e6;\n",[341,1229,1230],{"class":343,"line":1010},[341,1231,531],{"emptyLinePlaceholder":530},[341,1233,1234],{"class":343,"line":1015},[341,1235,1236],{},"        \u002F\u002F Test wrapping USDC through SwapFacility\n",[341,1238,1239],{"class":343,"line":1020},[341,1240,1241],{},"        \u002F\u002F Assert JMI tokens minted\n",[341,1243,1244],{"class":343,"line":1026},[341,1245,1246],{},"        \u002F\u002F Assert totalAssets increased\n",[341,1248,1249],{"class":343,"line":1031},[341,1250,568],{},[341,1252,1253],{"class":343,"line":1037},[341,1254,531],{"emptyLinePlaceholder":530},[341,1256,1257],{"class":343,"line":1042},[341,1258,1259],{},"    function testUnwrapLimitedToMBacking() public {\n",[341,1261,1263],{"class":343,"line":1262},45,[341,1264,1265],{},"        \u002F\u002F Setup: Wrap some M and some USDC\n",[341,1267,1269],{"class":343,"line":1268},46,[341,1270,1271],{},"        \u002F\u002F Try to unwrap more than M backing\n",[341,1273,1275],{"class":343,"line":1274},47,[341,1276,1277],{},"        \u002F\u002F Expect revert with InsufficientMBacking\n",[341,1279,1281],{"class":343,"line":1280},48,[341,1282,568],{},[341,1284,1286],{"class":343,"line":1285},49,[341,1287,531],{"emptyLinePlaceholder":530},[341,1289,1291],{"class":343,"line":1290},50,[341,1292,1293],{},"    function testReplaceAssetWithM() public {\n",[341,1295,1297],{"class":343,"line":1296},51,[341,1298,1299],{},"        \u002F\u002F Setup: Have USDC in the contract\n",[341,1301,1303],{"class":343,"line":1302},52,[341,1304,1305],{},"        \u002F\u002F Call replaceAssetWithM to swap M for USDC\n",[341,1307,1309],{"class":343,"line":1308},53,[341,1310,1311],{},"        \u002F\u002F Assert totalAssets decreased\n",[341,1313,1315],{"class":343,"line":1314},54,[341,1316,1317],{},"        \u002F\u002F Assert USDC sent to recipient\n",[341,1319,1321],{"class":343,"line":1320},55,[341,1322,568],{},[341,1324,1326],{"class":343,"line":1325},56,[341,1327,531],{"emptyLinePlaceholder":530},[341,1329,1331],{"class":343,"line":1330},57,[341,1332,1333],{},"    function testFreezing() public {\n",[341,1335,1337],{"class":343,"line":1336},58,[341,1338,1339],{},"        vm.prank(admin); \u002F\u002F Assuming admin has freeze manager role\n",[341,1341,1343],{"class":343,"line":1342},59,[341,1344,1345],{},"        token.freeze(user);\n",[341,1347,1349],{"class":343,"line":1348},60,[341,1350,1351],{},"        assertTrue(token.isFrozen(user));\n",[341,1353,1355],{"class":343,"line":1354},61,[341,1356,568],{},[341,1358,1360],{"class":343,"line":1359},62,[341,1361,531],{"emptyLinePlaceholder":530},[341,1363,1365],{"class":343,"line":1364},63,[341,1366,1367],{},"    function testYieldClaim() public {\n",[341,1369,1371],{"class":343,"line":1370},64,[341,1372,1373],{},"        \u002F\u002F Setup: Wrap M and let rewards accrue\n",[341,1375,1377],{"class":343,"line":1376},65,[341,1378,1379],{},"        \u002F\u002F Call claimYield\n",[341,1381,1383],{"class":343,"line":1382},66,[341,1384,1385],{},"        \u002F\u002F Assert rewards went to treasury\n",[341,1387,1389],{"class":343,"line":1388},67,[341,1390,568],{},[341,1392,1394],{"class":343,"line":1393},68,[341,1395,704],{},[311,1397,1399],{"id":1398},"_5-configure-supported-collateral","5. Configure Supported Collateral",[269,1401,1402],{},"After deployment, the asset cap manager must configure which collateral assets are accepted:",[332,1404,1406],{"className":511,"code":1405,"language":513,"meta":337,"style":337},"\u002F\u002F Set caps for each supported stablecoin\n\u002F\u002F Cap is in the asset's native decimals\n\n\u002F\u002F USDC (6 decimals) - 10M cap\nmyJMIToken.setAssetCap(USDC_ADDRESS, 10_000_000e6);\n\n\u002F\u002F DAI (18 decimals) - 5M cap\nmyJMIToken.setAssetCap(DAI_ADDRESS, 5_000_000e18);\n\n\u002F\u002F USDT (6 decimals) - 5M cap\nmyJMIToken.setAssetCap(USDT_ADDRESS, 5_000_000e6);\n",[306,1407,1408,1413,1418,1422,1427,1432,1436,1441,1446,1450,1455],{"__ignoreMap":337},[341,1409,1410],{"class":343,"line":344},[341,1411,1412],{},"\u002F\u002F Set caps for each supported stablecoin\n",[341,1414,1415],{"class":343,"line":358},[341,1416,1417],{},"\u002F\u002F Cap is in the asset's native decimals\n",[341,1419,1420],{"class":343,"line":417},[341,1421,531],{"emptyLinePlaceholder":530},[341,1423,1424],{"class":343,"line":423},[341,1425,1426],{},"\u002F\u002F USDC (6 decimals) - 10M cap\n",[341,1428,1429],{"class":343,"line":434},[341,1430,1431],{},"myJMIToken.setAssetCap(USDC_ADDRESS, 10_000_000e6);\n",[341,1433,1434],{"class":343,"line":445},[341,1435,531],{"emptyLinePlaceholder":530},[341,1437,1438],{"class":343,"line":451},[341,1439,1440],{},"\u002F\u002F DAI (18 decimals) - 5M cap\n",[341,1442,1443],{"class":343,"line":553},[341,1444,1445],{},"myJMIToken.setAssetCap(DAI_ADDRESS, 5_000_000e18);\n",[341,1447,1448],{"class":343,"line":559},[341,1449,531],{"emptyLinePlaceholder":530},[341,1451,1452],{"class":343,"line":565},[341,1453,1454],{},"\u002F\u002F USDT (6 decimals) - 5M cap\n",[341,1456,1457],{"class":343,"line":571},[341,1458,1459],{},"myJMIToken.setAssetCap(USDT_ADDRESS, 5_000_000e6);\n",[269,1461,1462,1465],{},[282,1463,1464],{},"Important:"," Only set caps for stablecoins that maintain a reliable 1:1 peg to the dollar. The JMI model assumes 1:1 peg for all accepted collateral.",[311,1467,1469],{"id":1468},"_6-gain-m0-earner-approval","6. Gain M0 Earner Approval",[269,1471,1472],{},"For your contract to accrue rewards on the supply it holds, its deployed address must be approved as an M0 Earner.",[711,1474,1475,1485],{},[326,1476,1477,1480,1481,1484],{},[282,1478,1479],{},"Calculate Your Address:"," Determine your contract's final deployment address using ",[306,1482,1483],{},"CREATE2"," or by deploying to a testnet first.",[326,1486,1487,1490,1491,1494,1495,1498],{},[282,1488,1489],{},"Submit a Proposal:"," Create and submit a proposal to add your contract's address to the ",[306,1492,1493],{},"earners"," list in the ",[306,1496,1497],{},"TTGRegistrar",".",[269,1500,1501,1502,1505],{},"For more details, see the ",[279,1503,1504],{"href":229},"Gaining Earner Approval"," guide.",[311,1507,1509],{"id":1508},"_7-security-audit","7. Security & Audit",[269,1511,1512],{},"Even though you are building on an audited template, any modifications should be thoroughly tested and independently audited:",[711,1514,1515,1518,1521],{},[326,1516,1517],{},"Write comprehensive tests covering all scenarios",[326,1519,1520],{},"Run static analysis tools like Slither",[326,1522,1523],{},"Engage a reputable security firm for a full audit if you've made significant modifications",[311,1525,1527],{"id":1526},"_8-deploy-launch","8. Deploy & Launch",[706,1529,1531],{"id":1530},"deploy-to-testnet-first","Deploy to Testnet First",[332,1533,1535],{"className":334,"code":1534,"language":336,"meta":337,"style":337},"source .env\n\nforge script script\u002FDeployMyJMIToken.s.sol \\\n    --rpc-url $SEPOLIA_RPC_URL \\\n    --verify \\\n    --etherscan-api-key $ETHERSCAN_API_KEY \\\n    --broadcast\n",[306,1536,1537,1545,1549,1563,1571,1578,1586],{"__ignoreMap":337},[341,1538,1539,1542],{"class":343,"line":344},[341,1540,1541],{"class":361},"source",[341,1543,1544],{"class":351}," .env\n",[341,1546,1547],{"class":343,"line":358},[341,1548,531],{"emptyLinePlaceholder":530},[341,1550,1551,1554,1557,1560],{"class":343,"line":417},[341,1552,1553],{"class":347},"forge",[341,1555,1556],{"class":351}," script",[341,1558,1559],{"class":351}," script\u002FDeployMyJMIToken.s.sol",[341,1561,1562],{"class":406}," \\\n",[341,1564,1565,1568],{"class":343,"line":423},[341,1566,1567],{"class":351},"    --rpc-url",[341,1569,1570],{"class":406}," $SEPOLIA_RPC_URL \\\n",[341,1572,1573,1576],{"class":343,"line":434},[341,1574,1575],{"class":351},"    --verify",[341,1577,1562],{"class":406},[341,1579,1580,1583],{"class":343,"line":445},[341,1581,1582],{"class":351},"    --etherscan-api-key",[341,1584,1585],{"class":406}," $ETHERSCAN_API_KEY \\\n",[341,1587,1588],{"class":343,"line":451},[341,1589,1590],{"class":351},"    --broadcast\n",[706,1592,1594],{"id":1593},"deploy-to-mainnet","Deploy to Mainnet",[332,1596,1598],{"className":334,"code":1597,"language":336,"meta":337,"style":337},"source .env\n\nforge script script\u002FDeployMyJMIToken.s.sol \\\n    --rpc-url $MAINNET_RPC_URL \\\n    --verify \\\n    --etherscan-api-key $ETHERSCAN_API_KEY \\\n    --broadcast\n",[306,1599,1600,1606,1610,1620,1627,1633,1639],{"__ignoreMap":337},[341,1601,1602,1604],{"class":343,"line":344},[341,1603,1541],{"class":361},[341,1605,1544],{"class":351},[341,1607,1608],{"class":343,"line":358},[341,1609,531],{"emptyLinePlaceholder":530},[341,1611,1612,1614,1616,1618],{"class":343,"line":417},[341,1613,1553],{"class":347},[341,1615,1556],{"class":351},[341,1617,1559],{"class":351},[341,1619,1562],{"class":406},[341,1621,1622,1624],{"class":343,"line":423},[341,1623,1567],{"class":351},[341,1625,1626],{"class":406}," $MAINNET_RPC_URL \\\n",[341,1628,1629,1631],{"class":343,"line":434},[341,1630,1575],{"class":351},[341,1632,1562],{"class":406},[341,1634,1635,1637],{"class":343,"line":445},[341,1636,1582],{"class":351},[341,1638,1585],{"class":406},[341,1640,1641],{"class":343,"line":451},[341,1642,1590],{"class":351},[706,1644,1646],{"id":1645},"hardware-wallet-deployment","Hardware Wallet Deployment",[269,1648,1649],{},"For production deployments:",[332,1651,1653],{"className":334,"code":1652,"language":336,"meta":337,"style":337},"forge script script\u002FDeployMyJMIToken.s.sol \\\n    --rpc-url $MAINNET_RPC_URL \\\n    --verify \\\n    --etherscan-api-key $ETHERSCAN_API_KEY \\\n    --ledger \\\n    --broadcast\n",[306,1654,1655,1665,1671,1677,1683,1690],{"__ignoreMap":337},[341,1656,1657,1659,1661,1663],{"class":343,"line":344},[341,1658,1553],{"class":347},[341,1660,1556],{"class":351},[341,1662,1559],{"class":351},[341,1664,1562],{"class":406},[341,1666,1667,1669],{"class":343,"line":358},[341,1668,1567],{"class":351},[341,1670,1626],{"class":406},[341,1672,1673,1675],{"class":343,"line":417},[341,1674,1575],{"class":351},[341,1676,1562],{"class":406},[341,1678,1679,1681],{"class":343,"line":423},[341,1680,1582],{"class":351},[341,1682,1585],{"class":406},[341,1684,1685,1688],{"class":343,"line":434},[341,1686,1687],{"class":351},"    --ledger",[341,1689,1562],{"class":406},[341,1691,1692],{"class":343,"line":445},[341,1693,1590],{"class":351},[706,1695,1697],{"id":1696},"enable-earning","Enable Earning",[269,1699,1700],{},"After deployment and earner approval:",[332,1702,1704],{"className":511,"code":1703,"language":513,"meta":337,"style":337},"myJMIToken.enableEarning();\n",[306,1705,1706],{"__ignoreMap":337},[341,1707,1708],{"class":343,"line":344},[341,1709,1703],{},[311,1711,1713],{"id":1712},"_9-integration-usage","9. Integration & Usage",[706,1715,1717],{"id":1716},"managing-asset-caps","Managing Asset Caps",[332,1719,1721],{"className":511,"code":1720,"language":513,"meta":337,"style":337},"\u002F\u002F Check current cap\nuint256 currentCap = myJMIToken.assetCap(USDC_ADDRESS);\n\n\u002F\u002F Update cap (only ASSET_CAP_MANAGER_ROLE)\nmyJMIToken.setAssetCap(USDC_ADDRESS, newCap);\n\n\u002F\u002F Disable an asset (set cap to 0)\nmyJMIToken.setAssetCap(USDC_ADDRESS, 0);\n",[306,1722,1723,1728,1733,1737,1742,1747,1751,1756],{"__ignoreMap":337},[341,1724,1725],{"class":343,"line":344},[341,1726,1727],{},"\u002F\u002F Check current cap\n",[341,1729,1730],{"class":343,"line":358},[341,1731,1732],{},"uint256 currentCap = myJMIToken.assetCap(USDC_ADDRESS);\n",[341,1734,1735],{"class":343,"line":417},[341,1736,531],{"emptyLinePlaceholder":530},[341,1738,1739],{"class":343,"line":423},[341,1740,1741],{},"\u002F\u002F Update cap (only ASSET_CAP_MANAGER_ROLE)\n",[341,1743,1744],{"class":343,"line":434},[341,1745,1746],{},"myJMIToken.setAssetCap(USDC_ADDRESS, newCap);\n",[341,1748,1749],{"class":343,"line":445},[341,1750,531],{"emptyLinePlaceholder":530},[341,1752,1753],{"class":343,"line":451},[341,1754,1755],{},"\u002F\u002F Disable an asset (set cap to 0)\n",[341,1757,1758],{"class":343,"line":553},[341,1759,1760],{},"myJMIToken.setAssetCap(USDC_ADDRESS, 0);\n",[706,1762,1764],{"id":1763},"checking-backing-status","Checking Backing Status",[332,1766,1768],{"className":511,"code":1767,"language":513,"meta":337,"style":337},"\u002F\u002F Total JMI supply\nuint256 totalSupply = myJMIToken.totalSupply();\n\n\u002F\u002F Non-M asset backing\nuint256 totalAssets = myJMIToken.totalAssets();\n\n\u002F\u002F M backing (what can be unwrapped)\nuint256 mBacking = totalSupply - totalAssets;\n\n\u002F\u002F Specific asset backing\nuint256 usdcBacking = myJMIToken.assetBalanceOf(USDC_ADDRESS);\n",[306,1769,1770,1775,1780,1784,1789,1794,1798,1803,1808,1812,1817],{"__ignoreMap":337},[341,1771,1772],{"class":343,"line":344},[341,1773,1774],{},"\u002F\u002F Total JMI supply\n",[341,1776,1777],{"class":343,"line":358},[341,1778,1779],{},"uint256 totalSupply = myJMIToken.totalSupply();\n",[341,1781,1782],{"class":343,"line":417},[341,1783,531],{"emptyLinePlaceholder":530},[341,1785,1786],{"class":343,"line":423},[341,1787,1788],{},"\u002F\u002F Non-M asset backing\n",[341,1790,1791],{"class":343,"line":434},[341,1792,1793],{},"uint256 totalAssets = myJMIToken.totalAssets();\n",[341,1795,1796],{"class":343,"line":445},[341,1797,531],{"emptyLinePlaceholder":530},[341,1799,1800],{"class":343,"line":451},[341,1801,1802],{},"\u002F\u002F M backing (what can be unwrapped)\n",[341,1804,1805],{"class":343,"line":553},[341,1806,1807],{},"uint256 mBacking = totalSupply - totalAssets;\n",[341,1809,1810],{"class":343,"line":559},[341,1811,531],{"emptyLinePlaceholder":530},[341,1813,1814],{"class":343,"line":565},[341,1815,1816],{},"\u002F\u002F Specific asset backing\n",[341,1818,1819],{"class":343,"line":571},[341,1820,1821],{},"uint256 usdcBacking = myJMIToken.assetBalanceOf(USDC_ADDRESS);\n",[706,1823,1825],{"id":1824},"claiming-rewards","Claiming Rewards",[332,1827,1829],{"className":511,"code":1828,"language":513,"meta":337,"style":337},"\u002F\u002F Check claimable rewards\nuint256 pendingYield = myJMIToken.yield();\n\n\u002F\u002F Claim rewards (anyone can call, goes to yieldRecipient)\nuint256 claimedAmount = myJMIToken.claimYield();\n",[306,1830,1831,1836,1841,1845,1850],{"__ignoreMap":337},[341,1832,1833],{"class":343,"line":344},[341,1834,1835],{},"\u002F\u002F Check claimable rewards\n",[341,1837,1838],{"class":343,"line":358},[341,1839,1840],{},"uint256 pendingYield = myJMIToken.yield();\n",[341,1842,1843],{"class":343,"line":417},[341,1844,531],{"emptyLinePlaceholder":530},[341,1846,1847],{"class":343,"line":423},[341,1848,1849],{},"\u002F\u002F Claim rewards (anyone can call, goes to yieldRecipient)\n",[341,1851,1852],{"class":343,"line":434},[341,1853,1854],{},"uint256 claimedAmount = myJMIToken.claimYield();\n",[706,1856,1858],{"id":1857},"managing-rewards-recipient","Managing Rewards Recipient",[332,1860,1862],{"className":511,"code":1861,"language":513,"meta":337,"style":337},"\u002F\u002F Only YIELD_RECIPIENT_MANAGER_ROLE\nmyJMIToken.setYieldRecipient(newTreasuryAddress);\n",[306,1863,1864,1869],{"__ignoreMap":337},[341,1865,1866],{"class":343,"line":344},[341,1867,1868],{},"\u002F\u002F Only YIELD_RECIPIENT_MANAGER_ROLE\n",[341,1870,1871],{"class":343,"line":358},[341,1872,1873],{},"myJMIToken.setYieldRecipient(newTreasuryAddress);\n",[706,1875,1877],{"id":1876},"freezing-addresses","Freezing Addresses",[332,1879,1881],{"className":511,"code":1880,"language":513,"meta":337,"style":337},"\u002F\u002F Only FREEZE_MANAGER_ROLE\nmyJMIToken.freeze(suspiciousAddress);\nmyJMIToken.unfreeze(clearedAddress);\n\n\u002F\u002F Batch operations\naddress[] memory toFreeze = new address[](3);\ntoFreeze[0] = addr1;\ntoFreeze[1] = addr2;\ntoFreeze[2] = addr3;\nmyJMIToken.freezeAccounts(toFreeze);\n",[306,1882,1883,1888,1893,1898,1902,1907,1912,1917,1922,1927],{"__ignoreMap":337},[341,1884,1885],{"class":343,"line":344},[341,1886,1887],{},"\u002F\u002F Only FREEZE_MANAGER_ROLE\n",[341,1889,1890],{"class":343,"line":358},[341,1891,1892],{},"myJMIToken.freeze(suspiciousAddress);\n",[341,1894,1895],{"class":343,"line":417},[341,1896,1897],{},"myJMIToken.unfreeze(clearedAddress);\n",[341,1899,1900],{"class":343,"line":423},[341,1901,531],{"emptyLinePlaceholder":530},[341,1903,1904],{"class":343,"line":434},[341,1905,1906],{},"\u002F\u002F Batch operations\n",[341,1908,1909],{"class":343,"line":445},[341,1910,1911],{},"address[] memory toFreeze = new address[](3);\n",[341,1913,1914],{"class":343,"line":451},[341,1915,1916],{},"toFreeze[0] = addr1;\n",[341,1918,1919],{"class":343,"line":553},[341,1920,1921],{},"toFreeze[1] = addr2;\n",[341,1923,1924],{"class":343,"line":559},[341,1925,1926],{},"toFreeze[2] = addr3;\n",[341,1928,1929],{"class":343,"line":565},[341,1930,1931],{},"myJMIToken.freezeAccounts(toFreeze);\n",[706,1933,1935],{"id":1934},"emergency-pause","Emergency Pause",[332,1937,1939],{"className":511,"code":1938,"language":513,"meta":337,"style":337},"\u002F\u002F Only PAUSER_ROLE\nmyJMIToken.pause();  \u002F\u002F Halts wrap, unwrap, transfer, replaceAssetWithM\nmyJMIToken.unpause(); \u002F\u002F Resumes operations\n",[306,1940,1941,1946,1951],{"__ignoreMap":337},[341,1942,1943],{"class":343,"line":344},[341,1944,1945],{},"\u002F\u002F Only PAUSER_ROLE\n",[341,1947,1948],{"class":343,"line":358},[341,1949,1950],{},"myJMIToken.pause();  \u002F\u002F Halts wrap, unwrap, transfer, replaceAssetWithM\n",[341,1952,1953],{"class":343,"line":417},[341,1954,1955],{},"myJMIToken.unpause(); \u002F\u002F Resumes operations\n",[706,1957,1959],{"id":1958},"frontend-integration","Frontend Integration",[332,1961,1965],{"className":1962,"code":1963,"language":1964,"meta":337,"style":337},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Get backing breakdown\nconst totalSupply = await myJMIToken.totalSupply();\nconst totalAssets = await myJMIToken.totalAssets();\nconst mBacking = totalSupply - totalAssets;\n\n\u002F\u002F Check specific asset backing\nconst usdcBacking = await myJMIToken.assetBalanceOf(USDC_ADDRESS);\nconst daisBacking = await myJMIToken.assetBalanceOf(DAI_ADDRESS);\n\n\u002F\u002F Check if wrap is allowed\nconst canWrap = await myJMIToken.isAllowedToWrap(USDC_ADDRESS, amount);\n\n\u002F\u002F Check if unwrap is allowed\nconst canUnwrap = await myJMIToken.isAllowedToUnwrap(amount);\n\n\u002F\u002F Check if asset replacement is allowed (amount in asset decimals)\nconst canReplace = await myJMIToken.isAllowedToReplaceAssetWithM(\n  USDC_ADDRESS,\n  assetAmount,\n);\n\n\u002F\u002F Get rewards info\nconst pendingYield = await myJMIToken.yield();\nconst yieldRecipient = await myJMIToken.yieldRecipient();\n\n\u002F\u002F Check account status\nconst isFrozen = await myJMIToken.isFrozen(userAddress);\nconst isPaused = await myJMIToken.paused();\n","javascript",[306,1966,1967,1972,1977,1982,1987,1991,1996,2001,2006,2010,2015,2020,2024,2029,2034,2038,2043,2048,2053,2058,2063,2067,2072,2077,2082,2086,2091,2096],{"__ignoreMap":337},[341,1968,1969],{"class":343,"line":344},[341,1970,1971],{},"\u002F\u002F Get backing breakdown\n",[341,1973,1974],{"class":343,"line":358},[341,1975,1976],{},"const totalSupply = await myJMIToken.totalSupply();\n",[341,1978,1979],{"class":343,"line":417},[341,1980,1981],{},"const totalAssets = await myJMIToken.totalAssets();\n",[341,1983,1984],{"class":343,"line":423},[341,1985,1986],{},"const mBacking = totalSupply - totalAssets;\n",[341,1988,1989],{"class":343,"line":434},[341,1990,531],{"emptyLinePlaceholder":530},[341,1992,1993],{"class":343,"line":445},[341,1994,1995],{},"\u002F\u002F Check specific asset backing\n",[341,1997,1998],{"class":343,"line":451},[341,1999,2000],{},"const usdcBacking = await myJMIToken.assetBalanceOf(USDC_ADDRESS);\n",[341,2002,2003],{"class":343,"line":553},[341,2004,2005],{},"const daisBacking = await myJMIToken.assetBalanceOf(DAI_ADDRESS);\n",[341,2007,2008],{"class":343,"line":559},[341,2009,531],{"emptyLinePlaceholder":530},[341,2011,2012],{"class":343,"line":565},[341,2013,2014],{},"\u002F\u002F Check if wrap is allowed\n",[341,2016,2017],{"class":343,"line":571},[341,2018,2019],{},"const canWrap = await myJMIToken.isAllowedToWrap(USDC_ADDRESS, amount);\n",[341,2021,2022],{"class":343,"line":576},[341,2023,531],{"emptyLinePlaceholder":530},[341,2025,2026],{"class":343,"line":582},[341,2027,2028],{},"\u002F\u002F Check if unwrap is allowed\n",[341,2030,2031],{"class":343,"line":588},[341,2032,2033],{},"const canUnwrap = await myJMIToken.isAllowedToUnwrap(amount);\n",[341,2035,2036],{"class":343,"line":594},[341,2037,531],{"emptyLinePlaceholder":530},[341,2039,2040],{"class":343,"line":600},[341,2041,2042],{},"\u002F\u002F Check if asset replacement is allowed (amount in asset decimals)\n",[341,2044,2045],{"class":343,"line":606},[341,2046,2047],{},"const canReplace = await myJMIToken.isAllowedToReplaceAssetWithM(\n",[341,2049,2050],{"class":343,"line":612},[341,2051,2052],{},"  USDC_ADDRESS,\n",[341,2054,2055],{"class":343,"line":618},[341,2056,2057],{},"  assetAmount,\n",[341,2059,2060],{"class":343,"line":624},[341,2061,2062],{},");\n",[341,2064,2065],{"class":343,"line":630},[341,2066,531],{"emptyLinePlaceholder":530},[341,2068,2069],{"class":343,"line":636},[341,2070,2071],{},"\u002F\u002F Get rewards info\n",[341,2073,2074],{"class":343,"line":642},[341,2075,2076],{},"const pendingYield = await myJMIToken.yield();\n",[341,2078,2079],{"class":343,"line":648},[341,2080,2081],{},"const yieldRecipient = await myJMIToken.yieldRecipient();\n",[341,2083,2084],{"class":343,"line":654},[341,2085,531],{"emptyLinePlaceholder":530},[341,2087,2088],{"class":343,"line":660},[341,2089,2090],{},"\u002F\u002F Check account status\n",[341,2092,2093],{"class":343,"line":666},[341,2094,2095],{},"const isFrozen = await myJMIToken.isFrozen(userAddress);\n",[341,2097,2098],{"class":343,"line":672},[341,2099,2100],{},"const isPaused = await myJMIToken.paused();\n",[311,2102,2104],{"id":2103},"_10-monitoring-maintenance","10. Monitoring & Maintenance",[706,2106,2108],{"id":2107},"key-metrics-to-track","Key Metrics to Track",[2110,2111,2112,2125],"table",{},[2113,2114,2115],"thead",{},[2116,2117,2118,2122],"tr",{},[2119,2120,2121],"th",{},"Metric",[2119,2123,2124],{},"Description",[2126,2127,2128,2137,2147,2155,2163,2174,2182],"tbody",{},[2116,2129,2130,2134],{},[2131,2132,2133],"td",{},"Total Supply",[2131,2135,2136],{},"Total JMI tokens in circulation",[2116,2138,2139,2142],{},[2131,2140,2141],{},"M Backing",[2131,2143,2144],{},[306,2145,2146],{},"totalSupply - totalAssets",[2116,2148,2149,2152],{},[2131,2150,2151],{},"Total Non-M Assets",[2131,2153,2154],{},"Sum of all collateral backings",[2116,2156,2157,2160],{},[2131,2158,2159],{},"Per-Asset Backing",[2131,2161,2162],{},"Individual collateral levels",[2116,2164,2165,2168],{},[2131,2166,2167],{},"Asset Utilization",[2131,2169,2170,2173],{},[306,2171,2172],{},"assetBalance \u002F assetCap"," per asset",[2116,2175,2176,2179],{},[2131,2177,2178],{},"Rewards Rate",[2131,2180,2181],{},"Current rewards accrual rate",[2116,2183,2184,2187],{},[2131,2185,2186],{},"Pending Rewards",[2131,2188,2189],{},"Unclaimed rewards amount",[706,2191,2193],{"id":2192},"operational-considerations","Operational Considerations",[323,2195,2196,2213,2231,2237,2253],{},[326,2197,2198,2201,2202],{},[282,2199,2200],{},"Monitor Asset Caps:"," Regularly review if caps need adjustment based on:\n",[711,2203,2204,2207,2210],{},[326,2205,2206],{},"Stablecoin peg stability",[326,2208,2209],{},"Market conditions",[326,2211,2212],{},"Protocol risk tolerance",[326,2214,2215,2218,2219,2222,2223],{},[282,2216,2217],{},"Rebalancing:"," Use ",[306,2220,2221],{},"replaceAssetWithM"," to rebalance backing when needed:\n",[711,2224,2225,2228],{},[326,2226,2227],{},"Arbitrageurs can swap approved collateral for approved stablecoin collateral.",[326,2229,2230],{},"This naturally moves the backing toward approved collateral over time.",[326,2232,2233,2236],{},[282,2234,2235],{},"Rewards Claiming:"," Set up automated rewards claiming if desired.",[326,2238,2239,2242],{},[282,2240,2241],{},"Emergency Procedures:",[711,2243,2244,2247,2250],{},[326,2245,2246],{},"Document pause\u002Funpause procedures.",[326,2248,2249],{},"Have freeze manager ready for suspicious activity.",[326,2251,2252],{},"Maintain secure communication channels for emergencies.",[326,2254,2255,2258],{},[282,2256,2257],{},"Collateral Monitoring:",[711,2259,2260,2263],{},[326,2261,2262],{},"Track peg stability of accepted stablecoins.",[326,2264,2265],{},"Be prepared to reduce\u002Fremove caps for depegged assets.",[269,2267,2268,2271],{},[282,2269,2270],{},"Congratulations!"," You now have a fully functional multi-collateral stablecoin that accepts various stablecoins while automatically accumulating rewards for your protocol.",[2273,2274,2275],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}",{"title":337,"searchDepth":344,"depth":358,"links":2277},[2278],{"id":300,"depth":358,"text":301,"children":2279},[2280,2281,2282,2283,2284,2285,2286,2287,2288,2289],{"id":313,"depth":417,"text":314},{"id":493,"depth":417,"text":494},{"id":806,"depth":417,"text":807},{"id":1047,"depth":417,"text":1048},{"id":1398,"depth":417,"text":1399},{"id":1468,"depth":417,"text":1469},{"id":1508,"depth":417,"text":1509},{"id":1526,"depth":417,"text":1527},{"id":1712,"depth":417,"text":1713},{"id":2103,"depth":417,"text":2104},"Step-by-step instructions for deploying a JMI (Just Mint It) stablecoin extension with multi-collateral support and centralized rewards distribution.","md",null,{},{"title":139,"description":2290},"b36aK6Wpx9xTq7xIgQuIavZII81kZbCTJJMW4bFeoEI",[2297,2299],{"title":135,"path":136,"stem":137,"description":2298,"children":-1},"Step-by-step instructions for deploying a Treasury Model stablecoin where 100% of rewards are captured by the use case owner.",{"title":131,"path":143,"stem":144,"description":2300,"children":-1},"Deep dive into the JMI (\"Just Mint It\") extension template which accepts multiple collateral types while directing 100% of rewards to a single recipient."]