[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"navigation":3,"\u002Fprotocol\u002Fdistribution-vault":260,"\u002Fprotocol\u002Fdistribution-vault-surround":1374},[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":192,"body":262,"description":1368,"extension":1369,"links":1370,"meta":1371,"navigation":815,"path":193,"seo":1372,"stem":194,"__hash__":1373},"docs\u002Fprotocol\u002Fdistribution-vault.md",{"type":263,"value":264,"toc":1341},"minimark",[265,278,282,285,289,292,321,324,338,345,349,352,361,364,369,393,398,418,423,476,480,483,487,503,507,576,583,589,593,613,617,676,680,683,687,753,757,833,837,840,844,870,874,910,914,1051,1055,1059,1062,1081,1085,1170,1174,1177,1249,1253,1256,1282,1289,1295,1313,1317,1320,1323,1337],[266,267,268,269,273,274,277],"p",{},"Also called ",[270,271,272],"code",{},"TTGVault"," or ",[270,275,276],{},"Vault",".",[279,280,166],"h2",{"id":281},"overview",[266,283,284],{},"The Distribution Vault is a core component of M0's economic infrastructure designed to collect, account for, and\ndistribute various forms of protocol revenue and yield to Zero token holders. It serves as the primary mechanism for\nvalue capture within the protocol's Two Token Governance (TTG) system, turning protocol operations into direct economic\nbenefits for governance participants.",[279,286,288],{"id":287},"purpose-and-role-in-the-ecosystem","Purpose and Role in the Ecosystem",[266,290,291],{},"The Distribution Vault functions as:",[293,294,295,303,309,315],"ol",{},[296,297,298,302],"li",{},[299,300,301],"strong",{},"Revenue Collector",": Accumulates various forms of protocol revenue from multiple sources",[296,304,305,308],{},[299,306,307],{},"Yield Distributor",": Enables proportional distribution of accumulated tokens to Zero token holders",[296,310,311,314],{},[299,312,313],{},"Value Capture Mechanism",": Creates a direct incentive for governance participation",[296,316,317,320],{},[299,318,319],{},"Economic Bridge",": Links protocol activity with governance token value",[279,322,162],{"id":323},"architecture-overview",[266,325,326,327,329,330,333,334,337],{},"The Distribution Vault is referenced throughout the system as ",[270,328,272],{}," or simply ",[270,331,332],{},"vault",". Its address is established\nduring deployment and made accessible to other core contracts via the ",[270,335,336],{},"Registrar"," or specific deployer contracts.",[266,339,340],{},[341,342],"img",{"alt":343,"src":344},"Adopted Guidance Change Process Flow","\u002Fimages\u002Ftechnical-documentations\u002Fdistribution-vault\u002Fdistribution-flow.png",[279,346,348],{"id":347},"revenue-sources","Revenue Sources",[266,350,351],{},"The Distribution Vault accumulates tokens from four primary sources:",[353,354,356,357,360],"h3",{"id":355},"_1-excess-yield-from-mintergateway","1. Excess Yield (from ",[270,358,359],{},"MinterGateway",")",[266,362,363],{},"This represents a continuous source of revenue coming from the interest rate spread between minters and earners.",[266,365,366],{},[299,367,368],{},"Mechanism:",[370,371,372,390],"ul",{},[296,373,374,375,378,379,382,383,386,387,389],{},"The ",[270,376,377],{},"MinterGateway.updateIndex()"," function calculates ",[270,380,381],{},"excessOwedM()"," - the difference between total owed ",[270,384,385],{},"$M"," (based on\nminter interest rate) and actual total ",[270,388,385],{}," supply (growing at the earner interest rate)",[296,391,392],{},"When positive, this excess amount is minted directly to the Distribution Vault",[266,394,395],{},[299,396,397],{},"Origin of Excess:",[370,399,400,406,412],{},[296,401,402,405],{},[299,403,404],{},"Interest Rate Spread",": The inherent difference between the higher interest rate charged to minters vs. the lower\nrate paid to earners (capped at 98% of the \"safe rate\")",[296,407,408,411],{},[299,409,410],{},"Rounding Differences",": Accumulated from principal-to-present value conversions within the continuous indexing math",[296,413,414,417],{},[299,415,416],{},"Penalties",": Charges imposed on minters for missed collateral updates or undercollateralization",[266,419,420],{},[299,421,422],{},"Code Implementation:",[424,425,430],"pre",{"className":426,"code":427,"language":428,"meta":429,"style":429},"language-solidity shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F In MinterGateway.sol\nfunction updateIndex() public override(IContinuousIndexing, ContinuousIndexing) returns (uint128 index_) {\n    uint240 excessOwedM_ = excessOwedM();\n    if (excessOwedM_ > 0) IMToken(mToken).mint(ttgVault, excessOwedM_); \u002F\u002F Mint $M to TTG Vault\n    index_ = super.updateIndex(); \u002F\u002F Update minter index and rate\n    IMToken(mToken).updateIndex(); \u002F\u002F Update earning index and rate\n}\n","solidity","",[270,431,432,440,446,452,458,464,470],{"__ignoreMap":429},[433,434,437],"span",{"class":435,"line":436},"line",1,[433,438,439],{},"\u002F\u002F In MinterGateway.sol\n",[433,441,443],{"class":435,"line":442},2,[433,444,445],{},"function updateIndex() public override(IContinuousIndexing, ContinuousIndexing) returns (uint128 index_) {\n",[433,447,449],{"class":435,"line":448},3,[433,450,451],{},"    uint240 excessOwedM_ = excessOwedM();\n",[433,453,455],{"class":435,"line":454},4,[433,456,457],{},"    if (excessOwedM_ > 0) IMToken(mToken).mint(ttgVault, excessOwedM_); \u002F\u002F Mint $M to TTG Vault\n",[433,459,461],{"class":435,"line":460},5,[433,462,463],{},"    index_ = super.updateIndex(); \u002F\u002F Update minter index and rate\n",[433,465,467],{"class":435,"line":466},6,[433,468,469],{},"    IMToken(mToken).updateIndex(); \u002F\u002F Update earning index and rate\n",[433,471,473],{"class":435,"line":472},7,[433,474,475],{},"}\n",[353,477,479],{"id":478},"_2-power-token-auction-proceeds-from-power-token","2. Power Token Auction Proceeds (from Power Token)",[266,481,482],{},"The Power token contract auctions off newly inflated tokens in non-voting epochs, with proceeds directed to the vault.",[266,484,485],{},[299,486,368],{},[370,488,489,492],{},[296,490,491],{},"Power token employs a Dutch auction mechanism where price decreases over time",[296,493,494,495,498,499,502],{},"When users purchase Power token via the ",[270,496,497],{},"buy()"," function, the calculated cost in ",[270,500,501],{},"cashToken"," is sent to the\nDistribution Vault",[266,504,505],{},[299,506,422],{},[424,508,510],{"className":426,"code":509,"language":428,"meta":429,"style":429},"\u002F\u002F In Power token.sol\nfunction buy(\n    uint256 minAmount_,\n    uint256 maxAmount_,\n    address destination_,\n    uint16 expiryEpoch_\n) external returns (uint240 amount_, uint256 cost_) {\n    \u002F\u002F ... calculations for amount_ and cost_ ...\n    emit Buy(msg.sender, amount_, cost_ = getCost(amount_));\n    _mint(destination_, amount_);\n    if (!ERC20Helper.transferFrom(cashToken(), msg.sender, vault, cost_)) revert TransferFromFailed();\n}\n",[270,511,512,517,522,527,532,537,542,547,553,559,565,571],{"__ignoreMap":429},[433,513,514],{"class":435,"line":436},[433,515,516],{},"\u002F\u002F In Power token.sol\n",[433,518,519],{"class":435,"line":442},[433,520,521],{},"function buy(\n",[433,523,524],{"class":435,"line":448},[433,525,526],{},"    uint256 minAmount_,\n",[433,528,529],{"class":435,"line":454},[433,530,531],{},"    uint256 maxAmount_,\n",[433,533,534],{"class":435,"line":460},[433,535,536],{},"    address destination_,\n",[433,538,539],{"class":435,"line":466},[433,540,541],{},"    uint16 expiryEpoch_\n",[433,543,544],{"class":435,"line":472},[433,545,546],{},") external returns (uint240 amount_, uint256 cost_) {\n",[433,548,550],{"class":435,"line":549},8,[433,551,552],{},"    \u002F\u002F ... calculations for amount_ and cost_ ...\n",[433,554,556],{"class":435,"line":555},9,[433,557,558],{},"    emit Buy(msg.sender, amount_, cost_ = getCost(amount_));\n",[433,560,562],{"class":435,"line":561},10,[433,563,564],{},"    _mint(destination_, amount_);\n",[433,566,568],{"class":435,"line":567},11,[433,569,570],{},"    if (!ERC20Helper.transferFrom(cashToken(), msg.sender, vault, cost_)) revert TransferFromFailed();\n",[433,572,574],{"class":435,"line":573},12,[433,575,475],{},[353,577,579,580,360],{"id":578},"_3-forfeited-standard-governor-proposal-fees-from-standardgovernor","3. Forfeited Standard Governor Proposal Fees (from ",[270,581,582],{},"StandardGovernor",[266,584,585,586,588],{},"Fees submitted with proposals in the ",[270,587,582],{}," flow to the Distribution Vault if the proposal fails.",[266,590,591],{},[299,592,368],{},[370,594,595,604,607],{},[296,596,597,598,601,602],{},"When creating a proposal via ",[270,599,600],{},"StandardGovernor.propose()",", proposers pay a fee in the system's ",[270,603,501],{},[296,605,606],{},"If the proposal succeeds, the fee is returned to the proposer",[296,608,609,610],{},"If the proposal is defeated or expires, the fee is sent to the Distribution Vault via ",[270,611,612],{},"sendProposalFeeToVault()",[266,614,615],{},[299,616,422],{},[424,618,620],{"className":426,"code":619,"language":428,"meta":429,"style":429},"\u002F\u002F In StandardGovernor.sol\nfunction sendProposalFeeToVault(uint256 proposalId_) external {\n    ProposalState state_ = state(proposalId_);\n    if (state_ != ProposalState.Expired && state_ != ProposalState.Defeated) revert FeeNotDestinedForVault(state_);\n    uint256 proposalFee_ = _proposalFees[proposalId_].fee;\n    if (proposalFee_ == 0) revert NoFeeToSend();\n    address cashToken_ = _proposalFees[proposalId_].cashToken;\n    delete _proposalFees[proposalId_];\n    emit ProposalFeeSentToVault(proposalId_, cashToken_, proposalFee_);\n    _transfer(cashToken_, vault, proposalFee_);\n}\n",[270,621,622,627,632,637,642,647,652,657,662,667,672],{"__ignoreMap":429},[433,623,624],{"class":435,"line":436},[433,625,626],{},"\u002F\u002F In StandardGovernor.sol\n",[433,628,629],{"class":435,"line":442},[433,630,631],{},"function sendProposalFeeToVault(uint256 proposalId_) external {\n",[433,633,634],{"class":435,"line":448},[433,635,636],{},"    ProposalState state_ = state(proposalId_);\n",[433,638,639],{"class":435,"line":454},[433,640,641],{},"    if (state_ != ProposalState.Expired && state_ != ProposalState.Defeated) revert FeeNotDestinedForVault(state_);\n",[433,643,644],{"class":435,"line":460},[433,645,646],{},"    uint256 proposalFee_ = _proposalFees[proposalId_].fee;\n",[433,648,649],{"class":435,"line":466},[433,650,651],{},"    if (proposalFee_ == 0) revert NoFeeToSend();\n",[433,653,654],{"class":435,"line":472},[433,655,656],{},"    address cashToken_ = _proposalFees[proposalId_].cashToken;\n",[433,658,659],{"class":435,"line":549},[433,660,661],{},"    delete _proposalFees[proposalId_];\n",[433,663,664],{"class":435,"line":555},[433,665,666],{},"    emit ProposalFeeSentToVault(proposalId_, cashToken_, proposalFee_);\n",[433,668,669],{"class":435,"line":561},[433,670,671],{},"    _transfer(cashToken_, vault, proposalFee_);\n",[433,673,674],{"class":435,"line":567},[433,675,475],{},[353,677,679],{"id":678},"_4-directarbitrary-transfers","4. Direct\u002FArbitrary Transfers",[266,681,682],{},"The Distribution Vault can receive tokens via direct transfers from any account or contract. These tokens need to be\nexplicitly \"registered\" for distribution.",[266,684,685],{},[299,686,368],{},[370,688,689,698,709,733],{},[296,690,691,692,273,695,277],{},"Tokens can be transferred directly to the vault contract address at any time using a standard\nERC20 ",[270,693,694],{},"transfer",[270,696,697],{},"transferFrom",[296,699,700,701,704,705,708],{},"To make these externally transferred tokens available for claiming, the external ",[270,702,703],{},"distribute(token)"," function must be\ncalled for the specific ",[270,706,707],{},"token_"," address.",[296,710,374,711,713,714,716,717,720,721,724,725,728,729,732],{},[270,712,703],{}," function calculates the increase in the vault's balance of ",[270,715,707],{}," since the last\ntime distribute was called for that token (using the internal ",[270,718,719],{},"_lastTokenBalances"," tracking). It then registers this\nnewly available amount (",[270,722,723],{},"amount_",") within the ",[270,726,727],{},"currentEpoch_"," (the epoch when ",[270,730,731],{},"distribute()"," is called).",[296,734,735,736,740,741,743,744,746,747,750,751,277],{},"Crucially, Zero token holders who held tokens ",[737,738,739],"em",{},"during"," this ",[270,742,727],{}," become eligible to claim a share of this\ndistributed ",[270,745,723],{},". The claimable share for each eligible holder is calculated pro-rata based on their fractional\nZero token ownership as snapshotted at the ",[737,748,749],{},"end"," of that specific ",[270,752,727],{},[266,754,755],{},[299,756,422],{},[424,758,760],{"className":426,"code":759,"language":428,"meta":429,"style":429},"\u002F\u002F In DistributionVault.sol\nfunction distribute(address token_) external returns (uint256 amount_) {\n    uint256 currentEpoch_ = clock();\n    amount_ = getDistributable(token_);\n    emit Distribution(token_, currentEpoch_, amount_);\n    unchecked {\n        distributionOfAt[token_][currentEpoch_] += amount_; \u002F\u002F Add to the distribution for the current epoch\n        _lastTokenBalances[token_] += amount_; \u002F\u002F Track this contract's latest balance\n    }\n}\n\nfunction getDistributable(address token_) public view returns (uint256) {\n    return IERC20(token_).balanceOf(address(this)) - _lastTokenBalances[token_];\n}\n",[270,761,762,767,772,777,782,787,792,797,802,807,811,817,822,828],{"__ignoreMap":429},[433,763,764],{"class":435,"line":436},[433,765,766],{},"\u002F\u002F In DistributionVault.sol\n",[433,768,769],{"class":435,"line":442},[433,770,771],{},"function distribute(address token_) external returns (uint256 amount_) {\n",[433,773,774],{"class":435,"line":448},[433,775,776],{},"    uint256 currentEpoch_ = clock();\n",[433,778,779],{"class":435,"line":454},[433,780,781],{},"    amount_ = getDistributable(token_);\n",[433,783,784],{"class":435,"line":460},[433,785,786],{},"    emit Distribution(token_, currentEpoch_, amount_);\n",[433,788,789],{"class":435,"line":466},[433,790,791],{},"    unchecked {\n",[433,793,794],{"class":435,"line":472},[433,795,796],{},"        distributionOfAt[token_][currentEpoch_] += amount_; \u002F\u002F Add to the distribution for the current epoch\n",[433,798,799],{"class":435,"line":549},[433,800,801],{},"        _lastTokenBalances[token_] += amount_; \u002F\u002F Track this contract's latest balance\n",[433,803,804],{"class":435,"line":555},[433,805,806],{},"    }\n",[433,808,809],{"class":435,"line":561},[433,810,475],{},[433,812,813],{"class":435,"line":567},[433,814,816],{"emptyLinePlaceholder":815},true,"\n",[433,818,819],{"class":435,"line":573},[433,820,821],{},"function getDistributable(address token_) public view returns (uint256) {\n",[433,823,825],{"class":435,"line":824},13,[433,826,827],{},"    return IERC20(token_).balanceOf(address(this)) - _lastTokenBalances[token_];\n",[433,829,831],{"class":435,"line":830},14,[433,832,475],{},[279,834,836],{"id":835},"distribution-mechanism","Distribution Mechanism",[266,838,839],{},"The Distribution Vault implements a sophisticated epoch-based, pro-rata distribution system that ensures fair allocation\nof accumulated tokens to Zero token holders.",[353,841,843],{"id":842},"core-mechanics","Core Mechanics",[293,845,846,852,858,864],{},[296,847,848,851],{},[299,849,850],{},"Epoch-Based Accounting",": Each token distribution is recorded in the current epoch (a time period, typically 15\ndays)",[296,853,854,857],{},[299,855,856],{},"Historical Balances",": Claims are calculated based on Zero token holders' balances during past epochs",[296,859,860,863],{},[299,861,862],{},"Pro-Rata Distribution",": Tokens are distributed proportionally to Zero token holdings",[296,865,866,869],{},[299,867,868],{},"Claimable Design",": Zero token holders must claim their share of distributed tokens",[353,871,873],{"id":872},"distribution-process","Distribution Process",[293,875,876,882,891,904],{},[296,877,878,881],{},[299,879,880],{},"Accumulation",": Tokens flow into the vault through various mechanisms",[296,883,884,887,888,890],{},[299,885,886],{},"Registration",": The ",[270,889,703],{}," function is called, recording the new token amount for the current epoch",[296,892,893,896,897,273,900,903],{},[299,894,895],{},"Claiming",": Zero token holders call ",[270,898,899],{},"claim()",[270,901,902],{},"claimBySig()"," to receive their share for specific epochs",[296,905,906,909],{},[299,907,908],{},"Calculation",": The claimable amount is computed based on the holder's proportional ownership during each claimed\nepoch",[353,911,913],{"id":912},"key-functions","Key Functions",[424,915,917],{"className":426,"code":916,"language":428,"meta":429,"style":429},"\u002F\u002F Allows claiming tokens for a specific address\nfunction claim(\n    address token_,\n    uint256 startEpoch_,\n    uint256 endEpoch_,\n    address destination_\n) external returns (uint256 claimed_)\n\n\u002F\u002F Allows claiming with a signature (helpful for gas-less transactions)\nfunction claimBySig(\n    address account_,\n    address token_,\n    uint256 startEpoch_,\n    uint256 endEpoch_,\n    address destination_,\n    uint256 deadline_,\n    bytes memory signature_\n) external returns (uint256 claimed_)\n\n\u002F\u002F Calculates the claimable amount for a given address, token, and epoch range\nfunction getClaimable(\n    address token_,\n    address account_,\n    uint256 startEpoch_,\n    uint256 endEpoch_\n) public view returns (uint256 claimable_)\n",[270,918,919,924,929,934,939,944,949,954,958,963,968,973,977,981,985,990,996,1002,1007,1012,1018,1024,1029,1034,1039,1045],{"__ignoreMap":429},[433,920,921],{"class":435,"line":436},[433,922,923],{},"\u002F\u002F Allows claiming tokens for a specific address\n",[433,925,926],{"class":435,"line":442},[433,927,928],{},"function claim(\n",[433,930,931],{"class":435,"line":448},[433,932,933],{},"    address token_,\n",[433,935,936],{"class":435,"line":454},[433,937,938],{},"    uint256 startEpoch_,\n",[433,940,941],{"class":435,"line":460},[433,942,943],{},"    uint256 endEpoch_,\n",[433,945,946],{"class":435,"line":466},[433,947,948],{},"    address destination_\n",[433,950,951],{"class":435,"line":472},[433,952,953],{},") external returns (uint256 claimed_)\n",[433,955,956],{"class":435,"line":549},[433,957,816],{"emptyLinePlaceholder":815},[433,959,960],{"class":435,"line":555},[433,961,962],{},"\u002F\u002F Allows claiming with a signature (helpful for gas-less transactions)\n",[433,964,965],{"class":435,"line":561},[433,966,967],{},"function claimBySig(\n",[433,969,970],{"class":435,"line":567},[433,971,972],{},"    address account_,\n",[433,974,975],{"class":435,"line":573},[433,976,933],{},[433,978,979],{"class":435,"line":824},[433,980,938],{},[433,982,983],{"class":435,"line":830},[433,984,943],{},[433,986,988],{"class":435,"line":987},15,[433,989,536],{},[433,991,993],{"class":435,"line":992},16,[433,994,995],{},"    uint256 deadline_,\n",[433,997,999],{"class":435,"line":998},17,[433,1000,1001],{},"    bytes memory signature_\n",[433,1003,1005],{"class":435,"line":1004},18,[433,1006,953],{},[433,1008,1010],{"class":435,"line":1009},19,[433,1011,816],{"emptyLinePlaceholder":815},[433,1013,1015],{"class":435,"line":1014},20,[433,1016,1017],{},"\u002F\u002F Calculates the claimable amount for a given address, token, and epoch range\n",[433,1019,1021],{"class":435,"line":1020},21,[433,1022,1023],{},"function getClaimable(\n",[433,1025,1027],{"class":435,"line":1026},22,[433,1028,933],{},[433,1030,1032],{"class":435,"line":1031},23,[433,1033,972],{},[433,1035,1037],{"class":435,"line":1036},24,[433,1038,938],{},[433,1040,1042],{"class":435,"line":1041},25,[433,1043,1044],{},"    uint256 endEpoch_\n",[433,1046,1048],{"class":435,"line":1047},26,[433,1049,1050],{},") public view returns (uint256 claimable_)\n",[279,1052,1054],{"id":1053},"technical-implementation-details","Technical Implementation Details",[353,1056,1058],{"id":1057},"contract-structure","Contract Structure",[266,1060,1061],{},"The Distribution Vault inherits from StatefulERC712, which provides EIP-712 signature verification functionality:",[424,1063,1065],{"className":426,"code":1064,"language":428,"meta":429,"style":429},"contract DistributionVault is IDistributionVault, StatefulERC712 {\n    \u002F\u002F ... implementation ...\n}\n",[270,1066,1067,1072,1077],{"__ignoreMap":429},[433,1068,1069],{"class":435,"line":436},[433,1070,1071],{},"contract DistributionVault is IDistributionVault, StatefulERC712 {\n",[433,1073,1074],{"class":435,"line":442},[433,1075,1076],{},"    \u002F\u002F ... implementation ...\n",[433,1078,1079],{"class":435,"line":448},[433,1080,475],{},[353,1082,1084],{"id":1083},"key-state-variables","Key State Variables",[424,1086,1088],{"className":426,"code":1087,"language":428,"meta":429,"style":429},"\u002F\u002F The scale to apply when accumulating an account's claimable token to minimize precision loss\nuint256 internal constant _GRANULARITY = 1e9;\n\n\u002F\u002F EIP-712 typehash for claim function\nbytes32 public constant CLAIM_TYPEHASH = 0x4b4633c3c305de33d5d9cf70f2712f26961648cd68d020c2556a9e43be58051d;\n\n\u002F\u002F Address of the Zero Token contract\naddress public immutable zeroToken;\n\n\u002F\u002F Mapping of last recorded balance per token\nmapping(address token => uint256 balance) internal _lastTokenBalances;\n\n\u002F\u002F Mapping of distributions per token, epoch, and amount\nmapping(address token => mapping(uint256 epoch => uint256 amount)) public distributionOfAt;\n\n\u002F\u002F Mapping of claimed status per token, epoch, and account\nmapping(address token => mapping(uint256 epoch => mapping(address account => bool claimed))) public hasClaimed;\n",[270,1089,1090,1095,1100,1104,1109,1114,1118,1123,1128,1132,1137,1142,1146,1151,1156,1160,1165],{"__ignoreMap":429},[433,1091,1092],{"class":435,"line":436},[433,1093,1094],{},"\u002F\u002F The scale to apply when accumulating an account's claimable token to minimize precision loss\n",[433,1096,1097],{"class":435,"line":442},[433,1098,1099],{},"uint256 internal constant _GRANULARITY = 1e9;\n",[433,1101,1102],{"class":435,"line":448},[433,1103,816],{"emptyLinePlaceholder":815},[433,1105,1106],{"class":435,"line":454},[433,1107,1108],{},"\u002F\u002F EIP-712 typehash for claim function\n",[433,1110,1111],{"class":435,"line":460},[433,1112,1113],{},"bytes32 public constant CLAIM_TYPEHASH = 0x4b4633c3c305de33d5d9cf70f2712f26961648cd68d020c2556a9e43be58051d;\n",[433,1115,1116],{"class":435,"line":466},[433,1117,816],{"emptyLinePlaceholder":815},[433,1119,1120],{"class":435,"line":472},[433,1121,1122],{},"\u002F\u002F Address of the Zero Token contract\n",[433,1124,1125],{"class":435,"line":549},[433,1126,1127],{},"address public immutable zeroToken;\n",[433,1129,1130],{"class":435,"line":555},[433,1131,816],{"emptyLinePlaceholder":815},[433,1133,1134],{"class":435,"line":561},[433,1135,1136],{},"\u002F\u002F Mapping of last recorded balance per token\n",[433,1138,1139],{"class":435,"line":567},[433,1140,1141],{},"mapping(address token => uint256 balance) internal _lastTokenBalances;\n",[433,1143,1144],{"class":435,"line":573},[433,1145,816],{"emptyLinePlaceholder":815},[433,1147,1148],{"class":435,"line":824},[433,1149,1150],{},"\u002F\u002F Mapping of distributions per token, epoch, and amount\n",[433,1152,1153],{"class":435,"line":830},[433,1154,1155],{},"mapping(address token => mapping(uint256 epoch => uint256 amount)) public distributionOfAt;\n",[433,1157,1158],{"class":435,"line":987},[433,1159,816],{"emptyLinePlaceholder":815},[433,1161,1162],{"class":435,"line":992},[433,1163,1164],{},"\u002F\u002F Mapping of claimed status per token, epoch, and account\n",[433,1166,1167],{"class":435,"line":998},[433,1168,1169],{},"mapping(address token => mapping(uint256 epoch => mapping(address account => bool claimed))) public hasClaimed;\n",[353,1171,1173],{"id":1172},"signature-based-claims","Signature-Based Claims",[266,1175,1176],{},"The Distribution Vault supports signature-based claims, allowing users to authorize others to claim on their behalf:",[424,1178,1180],{"className":426,"code":1179,"language":428,"meta":429,"style":429},"function claimBySig(\n    address account_,\n    address token_,\n    uint256 startEpoch_,\n    uint256 endEpoch_,\n    address destination_,\n    uint256 deadline_,\n    uint8 v_,\n    bytes32 r_,\n    bytes32 s_\n) external returns (uint256) {\n    \u002F\u002F ... signature verification logic ...\n    \u002F\u002F ... deadline verification ...\n    return _claim(account_, token_, startEpoch_, endEpoch_, destination_);\n}\n",[270,1181,1182,1186,1190,1194,1198,1202,1206,1210,1215,1220,1225,1230,1235,1240,1245],{"__ignoreMap":429},[433,1183,1184],{"class":435,"line":436},[433,1185,967],{},[433,1187,1188],{"class":435,"line":442},[433,1189,972],{},[433,1191,1192],{"class":435,"line":448},[433,1193,933],{},[433,1195,1196],{"class":435,"line":454},[433,1197,938],{},[433,1199,1200],{"class":435,"line":460},[433,1201,943],{},[433,1203,1204],{"class":435,"line":466},[433,1205,536],{},[433,1207,1208],{"class":435,"line":472},[433,1209,995],{},[433,1211,1212],{"class":435,"line":549},[433,1213,1214],{},"    uint8 v_,\n",[433,1216,1217],{"class":435,"line":555},[433,1218,1219],{},"    bytes32 r_,\n",[433,1221,1222],{"class":435,"line":561},[433,1223,1224],{},"    bytes32 s_\n",[433,1226,1227],{"class":435,"line":567},[433,1228,1229],{},") external returns (uint256) {\n",[433,1231,1232],{"class":435,"line":573},[433,1233,1234],{},"    \u002F\u002F ... signature verification logic ...\n",[433,1236,1237],{"class":435,"line":824},[433,1238,1239],{},"    \u002F\u002F ... deadline verification ...\n",[433,1241,1242],{"class":435,"line":830},[433,1243,1244],{},"    return _claim(account_, token_, startEpoch_, endEpoch_, destination_);\n",[433,1246,1247],{"class":435,"line":987},[433,1248,475],{},[279,1250,1252],{"id":1251},"economic-implications","Economic Implications",[266,1254,1255],{},"The Distribution Vault creates several important economic effects:",[293,1257,1258,1264,1270,1276],{},[296,1259,1260,1263],{},[299,1261,1262],{},"Zero Token Value Accrual",": By directing protocol revenue to Zero token holders, it increases the token's economic\nvalue",[296,1265,1266,1269],{},[299,1267,1268],{},"Governance Incentive Alignment",": Creates a direct financial incentive for governance participation",[296,1271,1272,1275],{},[299,1273,1274],{},"Sustainable Protocol Economics",": Ensures that excess yield and protocol fees flow back to governance participants",[296,1277,1278,1281],{},[299,1279,1280],{},"Diversified Revenue Streams",": Collects different token types from multiple sources, creating a robust revenue\nmodel",[279,1283,1285,1286,1288],{"id":1284},"integration-with-the-wrapped-m-token-extended","Integration with the Wrapped ",[270,1287,385],{}," Token (Extended)",[266,1290,1291,1292,1294],{},"The Distribution Vault also interacts with the Wrapped ",[270,1293,385],{}," (wM) system:",[293,1296,1297,1307],{},[296,1298,1299,1302,1303,1306],{},[299,1300,1301],{},"Excess Yield Destination",": The wM contract can send excess yield to the Distribution Vault via its ",[270,1304,1305],{},"claimExcess()","\nfunction",[296,1308,1309,1312],{},[299,1310,1311],{},"Economic Loop Completion",": This creates a complete economic loop where even wrapped token operations can generate\nvalue for governance participants",[279,1314,1316],{"id":1315},"conclusion","Conclusion",[266,1318,1319],{},"The Distribution Vault stands as a critical infrastructure component in the M0 protocol, serving as the central hub for\nvalue capture and redistribution. Through its sophisticated pro-rata distribution mechanism, it ensures that protocol\noperations consistently generate value for governance participants, creating strong economic incentives for system\nparticipation and alignment.",[266,1321,1322],{},"By collecting revenue from multiple sources and making it claimable by Zero token holders, the vault creates a direct\nfinancial link between protocol usage and governance value, strengthening the economic sustainability of the entire\necosystem.",[266,1324,1325,1326,1333,1334,1336],{},"One can check straight on the ",[1327,1328,1332],"a",{"href":1329,"rel":1330},"http:\u002F\u002Fdashboard.m0.org",[1331],"nofollow","dashboard"," the number of ",[270,1335,385],{}," accumulated by the vault and not\nclaimed so far.",[1338,1339,1340],"style",{},"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);}",{"title":429,"searchDepth":436,"depth":442,"links":1342},[1343,1344,1345,1346,1354,1359,1364,1365,1367],{"id":281,"depth":442,"text":166},{"id":287,"depth":442,"text":288},{"id":323,"depth":442,"text":162},{"id":347,"depth":442,"text":348,"children":1347},[1348,1350,1351,1353],{"id":355,"depth":448,"text":1349},"1. Excess Yield (from MinterGateway)",{"id":478,"depth":448,"text":479},{"id":578,"depth":448,"text":1352},"3. Forfeited Standard Governor Proposal Fees (from StandardGovernor)",{"id":678,"depth":448,"text":679},{"id":835,"depth":442,"text":836,"children":1355},[1356,1357,1358],{"id":842,"depth":448,"text":843},{"id":872,"depth":448,"text":873},{"id":912,"depth":448,"text":913},{"id":1053,"depth":442,"text":1054,"children":1360},[1361,1362,1363],{"id":1057,"depth":448,"text":1058},{"id":1083,"depth":448,"text":1084},{"id":1172,"depth":448,"text":1173},{"id":1251,"depth":442,"text":1252},{"id":1284,"depth":442,"text":1366},"Integration with the Wrapped $M Token (Extended)",{"id":1315,"depth":442,"text":1316},"Documentation of the Distribution Vault (TTGVault), the core component for collecting and distributing protocol revenue to Zero token holders.","md",null,{},{"title":192,"description":1368},"44QOuEvG_ZfvubHTvjggDJNcwP0WWGXJaft0oeYjdEE",[1375,1377],{"title":183,"path":184,"stem":185,"description":1376,"children":-1},"Qualified financial institutions can integrate with M0's Stablecoin Core to issue stablecoins.",{"title":196,"path":197,"stem":198,"description":1378,"children":-1},"Documentation of M0 Extensions, the application layer for building custom stablecoins on the M0 platform, including the SwapFacility for seamless 1:1 conversions."]