diff --git a/specs/protocol/mint-manager.md b/specs/protocol/mint-manager.md new file mode 100644 index 0000000..780b7e6 --- /dev/null +++ b/specs/protocol/mint-manager.md @@ -0,0 +1,129 @@ +# MintManager + + + + +**Table of Contents** + +- [MintManager](#mintmanager) + - [Overview](#overview) + - [Mint Token Transaction Type](#mint-token-transaction-type) + - [Mint Token Caller Account](#mint-token-caller-account) + - [How to Determine a Mint Amount](#how-to-determine-a-mint-amount) + - [Distribution](#distribution) + - [Initial Minting and Distribution](#initial-minting-and-distribution) + + + + + +[g-transaction-type]: ../glossary.md#transaction-type +[g-deposited]: ../glossary.md#deposited-transaction +[g-l1-attr-deposit]: ../glossary.md#l1-attributes-deposited-transaction +[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`. + +## Mint Token Transaction Type + +[mint-token-tx-type]: #mint-token-transaction-type + +We define a new [EIP-2718] compatible transaction type with the prefix `0x70` to represent a mint token transaction. + +[EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718 + +In contrast to [EIP-155] transactions, this transaction type: + +- Does not include signature information, and makes the `from` address explicit. + API responses contain zeroed signature `v`, `r`, `s` values for backwards compatibility. +- Does not include the ETH value. API responses contain zero ETH value for backwards compatibility. + +The mint token transaction follows directly after the [L1 attributes deposited transaction][g-l1-attr-deposit]. +This transaction calls the `mint()` function of the `MintManager` contract on L2. +The `from` of the transaction is always a system account, and the `to` is the `MintManager` contract address. +Like the [Deposited Transaction][g-deposited], this transaction does not have a signature, and users cannot execute it. + +This transaction MUST have the following values: + +1. `from` is `0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001` (the address of the + [Mint token caller account][mint-token-caller-account]) +2. `to` is `0x420000000000000000000000000000000000070` (the address of the `MintManager` contract). +3. `gasLimit` is set to `1,000,000`. +4. `nonce` is set to the current L2 block number. +5. `data` is an [ABI] encoded call to the `MintManager`'s `mint()` function. + +This transaction type is not charged any ETH for its allocated `gasLimit`, +as it is effectively part of the state-transition processing. + +### Mint Token Caller Account + +[mint-token-caller-account]: #mint-token-caller-account + +The mint token caller account is an [EOA][g-eoa] with no known private key. It has the address +`0xdeaddeaddeaddeaddeaddeaddeaddeaddead0070`. Its value is returned by the `CALLER` and `ORIGIN` +opcodes during execution of the mint token transaction. + +## How to Determine a Mint 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 // SLIDING_WINDOW_BLOCKS + 1 + + if block_number % SLIDING_WINDOW_BLOCKS == 0: + epoch = epoch - 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` + +## 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. + +## Initial Minting and Distribution + +Mints the amount of tokens that should have been minted from the genesis block to the current block. +This function operates only if the total supply of the `GovernanceToken` is 0. + +```python +def initial_mint(block_number): + if supply > 0: + return + + amount = 0 + mint_per_block = INIT_MINT_PER_BLOCK + epoch = block_number // SLIDING_WINDOW + 1 + offset = block_number % SLIDING_WINDOW + + 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 + +```