diff --git a/specs/glossary.md b/specs/glossary.md index 90f2171..5ca8aa1 100644 --- a/specs/glossary.md +++ b/specs/glossary.md @@ -26,7 +26,6 @@ - [Priority Gas Auction](#priority-gas-auction) - [Sequencing](#sequencing) - [Sequencer](#sequencer) - - [Maximal Extractable Value](#maximal-extractable-value) - [Sequencing Window](#sequencing-window) - [Sequencing Epoch](#sequencing-epoch) - [L1 Origin](#l1-origin) diff --git a/specs/protocol/deposits.md b/specs/protocol/deposits.md index dce88a5..5beb815 100644 --- a/specs/protocol/deposits.md +++ b/specs/protocol/deposits.md @@ -17,6 +17,7 @@ - [L1 Attributes Depositor Account](#l1-attributes-depositor-account) - [L1 Attributes Predeployed Contract](#l1-attributes-predeployed-contract) - [L1 Attributes Predeployed Contract: Reference Implementation](#l1-attributes-predeployed-contract-reference-implementation) + - [Mint Token](#mint-token) - [User-Deposited Transactions](#user-deposited-transactions) - [Deposit Contract](#deposit-contract) - [Address Aliasing](#address-aliasing) @@ -305,6 +306,11 @@ After running `pnpm build` in the `packages/contracts` directory, the bytecode t file will be located in the `deployedBytecode` field of the build artifacts file at `/packages/contracts/artifacts/contracts/L2/L1Block.sol/L1Block.json`. +#### Mint Token + +After storing all attributes of the L1 block, call the mint function of the MintManager contract to mint tokens. +See [MintManager](./mint-manager.md) specification. + ## User-Deposited Transactions [user-deposited]: #user-deposited-transactions diff --git a/specs/protocol/mint-manager.md b/specs/protocol/mint-manager.md new file mode 100644 index 0000000..4b2cd80 --- /dev/null +++ b/specs/protocol/mint-manager.md @@ -0,0 +1,108 @@ +# MintManager + + + + +- [Overview](#overview) +- [Activation](#activation) +- [Calculating Minting Amount](#calculating-minting-amount) +- [Initial Minting](#initial-minting) +- [Distribution](#distribution) + + + + + +[g-deposited]: ../glossary.md#deposited-transaction +[g-l1-attr-deposit]: ../glossary.md#l1-attributes-deposited-transaction +[g-l1-attr-predeploy]: glossary.md#l1-attributes-predeployed-contract +[g-eoa]: ../glossary.md#eoa + +## Overview + +The `GovernanceToken` of Kroma is minted every block by the `MintManager` contract on L2 and distributed to recipients. +`MintManager` is a predeployed contract on L2 at address `0x4200000000000000000000000000000000000070`. + +In the [L1 Attributes Deposited Transaction][g-l1-attr-deposit], the [L1 Attributes Predeployed Contract][g-l1-attr-predeploy] calls the mint function of the MintManager contract to mint tokens. + +> Note that the mint function of the MintManager contract can only called by the +[L1 Attributes Predeployed Contract][g-l1-attr-predeploy] + +## Activation + +The mint function is activated from a specific L2 block number, +which is recorded in an immutable variable named `MINT_ACTIVATED_BLOCK`. +If the mint function is called before the activation block number, nothing will happen (it will not revert). + +## Calculating Minting Amount + +The amount of `GovernanceToken` minted per block decreases periodically. +The amount to be minted is calculated by repeatedly applying decay based on the current block number for a +certain number of epochs. +An epoch can be calculated by dividing the current block number by `SLIDING_WINDOW_BLOCKS` value. + +Only up to 8 decimal places are considered for the minting amount. + +```python +def get_mint_amount_per_block(block_number): + epoch = (block_number - 1) // SLIDING_WINDOW + 1 + offset = (block_number - 1) % SLIDING_WINDOW + 1 + + mint_amount = INIT_MINT_PER_BLOCK + for i in range(1, epoch): + mint_amount = (mint_amount * DECAYING_FACTOR) // DECAYING_DENOMINATOR + mint_amount = mint_amount // FLOOR_UNIT * FLOOR_UNIT + + return mint_amount +``` + +- `SLIDING_WINDOW_BLOCKS`: The period (in blocks) which the mint amount decreases. +- `INIT_MINT_PER_BLOCK`: The amount minted per block during the first epoch. +- `DECAYING_FACTOR`: The ratio by which the mint amount decreases from the previous period. +- `DECAYING_DENOMINATOR`: The denominator of the decaying factor. This value is `10^5`. +- `FLOOR_UNIT`: The unit for rounding down decimal places. Since the decimal places for `GovernanceToken` are 18, + and the mint amount is considered up to 8 decimal places, this value is `10^10` + +## Initial Minting + +Mints the amount of tokens that should have been minted from the genesis block to the current block. +This function operates only if it has never been minted through the MintManager contract before. + +```python +def initial_mint_amount(block_number): + amount = 0 + mint_per_block = INIT_MINT_PER_BLOCK + epoch = (block_number - 1) // SLIDING_WINDOW + 1 + offset = (block_number - 1) % SLIDING_WINDOW + 1 + + for i in range(1, epoch): + amount = amount + mint_per_block * SLIDING_WINDOW + mint_per_block = (mint_per_block * DECAYING_FACTOR) // DECAYING_DENOMINATOR + mint_per_block = (mint_per_block // FLOOR_UNIT) * FLOOR_UNIT + + if offset > 0: + amount = amount + mint_per_block * offset + + return amount +``` + +## Distribution + +After deploying the MintManager contract, the recipient addresses and their respective share percentages +are set during initialization. +The minted amount for the current block is then distributed to the configured addresses. + +```python +mint_amount_per_block = get_mint_amount_per_block(block_number) + +for i in range(len(recipients)): + recipient = recipients[i] + shares = shares[i] + amount = mint_amount_per_block * shares / SHARE_DENOMINATOR + + governance_token_mint(recipient, amount) + +last_minted_block = block_number +``` + +- `SHARE_DENOMINATOR`: The denominator of the share. This value is `10^5`. diff --git a/specs/protocol/validator.md b/specs/protocol/validator.md index bdde3a0..a53dfb4 100644 --- a/specs/protocol/validator.md +++ b/specs/protocol/validator.md @@ -4,6 +4,7 @@ **Table of Contents** +- [Overview](#overview) - [Submitting L2 Output Commitments](#submitting-l2-output-commitments) - [L2 Output Commitment Construction](#l2-output-commitment-construction) - [Output Payload(Version 0)](#output-payloadversion-0)