Skip to content

feat: improved tokenomics#119

Open
SIDDHANTCOOKIE wants to merge 2 commits into
feat/timestamp-pow-validationfrom
feat/improved-tokenomics
Open

feat: improved tokenomics#119
SIDDHANTCOOKIE wants to merge 2 commits into
feat/timestamp-pow-validationfrom
feat/improved-tokenomics

Conversation

@SIDDHANTCOOKIE

@SIDDHANTCOOKIE SIDDHANTCOOKIE commented Jul 8, 2026

Copy link
Copy Markdown
Member

This PR significantly improves the MiniChain tokenomics and transaction model by migrating away from flat fees to an EIP-1559 style structure. It also establishes a clear, declarative tokenomics specification in the genesis configuration.

Screenshots/Recordings:

TODO: If applicable, add screenshots or recordings that demonstrate the interface before and after the changes.

Additional Notes:

  • Transaction Model: Replaced the static fee property with gas_limit and max_fee_per_gas across the protocol.
  • Gas Refunds: Transactions now deduct the theoretical maximum upfront cost (amount + (gas_limit * max_fee_per_gas)). If the transaction succeeds and uses less gas than the limit, the unspent gas is refunded to the sender.
  • Miner Incentives: mempool.py now sorts pending transactions by the highest max_fee_per_gas offered, rather than a flat fee, aligning miner incentives. The total block reward accounts for the exact gas_used by each transaction.
  • Genesis Tokenomics: Added an initial_supply parameter (set to 1,500,000,000) to genesis.json to clearly document the network's maximum genesis issuance, clarifying the intent of the alloc balances.
  • CLI: The send, deploy, and call terminal commands have been updated to accept [gas_limit] and [max_fee_per_gas].

AI Usage Disclosure:

We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact. AI slop is strongly discouraged and may lead to banning and blocking. Do not spam our repos with AI slop.

Check one of the checkboxes below:

  • This PR does not contain AI-generated code at all.
  • This PR contains AI-generated code. I have read the AI Usage Policy and this PR complies with this policy. I have tested the code locally and I am responsible for it.

I have used the following AI models and tools: TODO

Checklist

  • My PR addresses a single issue, fixes a single bug or makes a single improvement.
  • My code follows the project's code style and conventions
  • If applicable, I have made corresponding changes or additions to the documentation
  • If applicable, I have made corresponding changes or additions to tests
  • My changes generate no new warnings or errors
  • I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • I have read the Contribution Guidelines
  • Once I submit my PR, CodeRabbit AI will automatically review it and I will address CodeRabbit's comments.
  • I have filled this PR template completely and carefully, and I understand that my PR may be closed without review otherwise.

Summary by CodeRabbit

  • New Features

    • Transactions now support separate gas limit and max fee settings for sends, contract deployments, and contract calls.
    • Mining rewards now include transaction fees based on gas used and the configured max fee.
    • Genesis configuration now includes an initial token supply value.
  • Bug Fixes

    • Transaction validation, balance deductions, refunds, and receipts now follow the updated gas-based fee model consistently.
    • Mempool ordering now respects the new fee setting when prioritizing transactions.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Replaces the flat transaction fee field with gas_limit and max_fee_per_gas throughout the codebase: Transaction model, State validation/application (cost, refund logic), mempool ordering, mining reward calculation, CLI parsing/commands, and genesis config. Test suites are updated to match the new constructor signature.

Changes

Gas-based fee model

Layer / File(s) Summary
Transaction data model and signing payload
minichain/transaction.py
_TX_FIELDS, __init__, to_dict, to_signing_dict, from_dict switch from fee to gas_limit/max_fee_per_gas, changing signed payload bytes.
State validation and gas cost application
minichain/state.py
verify_transaction_logic, _amounts_well_formed, _apply_validated_tx compute cost as amount + gas_limit*max_fee_per_gas and refund gas_refund*max_fee_per_gas across deploy, call, and transfer paths.
Mempool ordering and mining reward
minichain/mempool.py, minichain/chain.py, main.py
Mempool insertion ordering and mining reward totals now use max_fee_per_gas-based fee sums instead of raw fee/gas_used.
CLI transaction parameter parsing
main.py
New parse_tx_params helper replaces parse_amount_fee; send/deploy/call commands parse and construct transactions with gas_limit/max_fee_per_gas.
Genesis initial supply field
genesis.json
Adds top-level initial_supply value of 1500000000.
Test suite updates
tests/test_contract.py, tests/test_contract_transfers.py, tests/test_core.py, tests/test_reorg.py
All Transaction constructions updated to use gas_limit/max_fee_per_gas instead of fee, with assertions kept consistent.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: Python Lang

Suggested reviewers: Zahnentferner

Poem

A rabbit hops through gas and limit,
Fees no more a single digit,
max_fee_per_gas now sets the pace,
Refunds bounce back in their place,
Hop, hop, hooray — the chain's in shape! 🐇⛽

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is related to the PR’s fee and supply/tokenomics changes, though it is broader than the specific implementation.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/improved-tokenomics

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@SIDDHANTCOOKIE

Copy link
Copy Markdown
Member Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@genesis.json`:
- Line 7: The new top-level initial_supply field is not used by the genesis
loading path, so either wire it into the chain initialization flow or remove it
from the genesis schema. Update the genesis handling in minichain/chain.py,
especially the code that currently reads alloc during startup, so initial supply
is actually applied at runtime; otherwise, delete the unused initial_supply
entry to keep the genesis config accurate.

In `@main.py`:
- Around line 411-423: The send command is duplicating parsing and validation
that already exists in parse_tx_params, and the messages are diverging. Update
the send flow to delegate integer parsing and non-negativity checks to
parse_tx_params(parts, 2), then keep only the send-specific amount > 0
validation in the send handler. Make sure the logic stays aligned with the
existing deploy and call paths by reusing parse_tx_params rather than
re-implementing the checks in this block.

In `@minichain/state.py`:
- Around line 213-217: The refund logic in the transaction processing path is
unreachable because `gas_used` is being set to `tx.gas_limit`, which makes
`gas_refund` always zero. Update the transfer handling in the relevant state
transition method to either calculate a real intrinsic gas cost for simple
transfers and use that for `gas_used`, or remove the refund branch entirely if
full-limit billing is intended. Use the `gas_used`, `gas_refund`, and `Receipt`
flow in `minichain/state.py` as the place to adjust this behavior.
- Around line 141-144: The deploy refund logic in state processing is dead
because gas_used is always set from tx.gas_limit, making gas_refund permanently
zero. Update the deploy handling in state.py around the tx gas accounting path
to either compute real deployment gas usage before refunding or remove the
unreachable gas_refund branch and its sender balance adjustment for clarity. Use
the existing tx, gas_used, gas_refund, and sender balance update logic to locate
and simplify this block.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f33fd8a3-4045-446f-af5e-deca2e41fd53

📥 Commits

Reviewing files that changed from the base of the PR and between 1335026 and 328d2ce.

📒 Files selected for processing (10)
  • genesis.json
  • main.py
  • minichain/chain.py
  • minichain/mempool.py
  • minichain/state.py
  • minichain/transaction.py
  • tests/test_contract.py
  • tests/test_contract_transfers.py
  • tests/test_core.py
  • tests/test_reorg.py

Comment thread genesis.json
"difficulty": 4,
"target_block_time": 10000,
"alpha": 0.1,
"initial_supply": 1500000000,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Wire initial_supply into genesis loading or remove it.

minichain/chain.py still initializes balances from alloc only, so this new top-level field has no runtime effect and can mislead operators about the actual genesis issuance.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@genesis.json` at line 7, The new top-level initial_supply field is not used
by the genesis loading path, so either wire it into the chain initialization
flow or remove it from the genesis schema. Update the genesis handling in
minichain/chain.py, especially the code that currently reads alloc during
startup, so initial supply is actually applied at runtime; otherwise, delete the
unused initial_supply entry to keep the genesis config accurate.

Comment thread main.py Outdated
Comment on lines 411 to 423
try:
amount = int(parts[2])
fee = int(parts[3]) if len(parts) > 3 else 0
gas_limit = int(parts[3]) if len(parts) > 3 else 0
max_fee = int(parts[4]) if len(parts) > 4 else 0
except ValueError:
print(" Amount and fee must be integers.")
print(" Values must be integers.")
continue
if amount <= 0:
print(" Amount must be greater than 0.")
continue
if fee < 0:
print(" Fee cannot be negative.")
if gas_limit < 0 or max_fee < 0:
print(" Gas limit and max fee cannot be negative.")
continue

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reuse parse_tx_params in send to avoid duplicated, already-diverging parsing.

This block re-implements the integer parsing and non-negativity checks that parse_tx_params(parts, 2) already provides, and the error strings have started to diverge ("Gas limit and max fee cannot be negative." vs. the helper's "Values cannot be negative."). Delegating to the helper keeps send, deploy, and call consistent; only the amount <= 0 rule is specific to send.

♻️ Proposed refactor
-            try:
-                amount = int(parts[2])
-                gas_limit = int(parts[3]) if len(parts) > 3 else 0
-                max_fee = int(parts[4]) if len(parts) > 4 else 0
-            except ValueError:
-                print("  Values must be integers.")
-                continue
-            if amount <= 0:
-                print("  Amount must be greater than 0.")
-                continue
-            if gas_limit < 0 or max_fee < 0:
-                print("  Gas limit and max fee cannot be negative.")
-                continue
+            parsed = parse_tx_params(parts, 2)
+            if parsed is None:
+                continue
+            amount, gas_limit, max_fee = parsed
+            if amount <= 0:
+                print("  Amount must be greater than 0.")
+                continue
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try:
amount = int(parts[2])
fee = int(parts[3]) if len(parts) > 3 else 0
gas_limit = int(parts[3]) if len(parts) > 3 else 0
max_fee = int(parts[4]) if len(parts) > 4 else 0
except ValueError:
print(" Amount and fee must be integers.")
print(" Values must be integers.")
continue
if amount <= 0:
print(" Amount must be greater than 0.")
continue
if fee < 0:
print(" Fee cannot be negative.")
if gas_limit < 0 or max_fee < 0:
print(" Gas limit and max fee cannot be negative.")
continue
parsed = parse_tx_params(parts, 2)
if parsed is None:
continue
amount, gas_limit, max_fee = parsed
if amount <= 0:
print(" Amount must be greater than 0.")
continue
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@main.py` around lines 411 - 423, The send command is duplicating parsing and
validation that already exists in parse_tx_params, and the messages are
diverging. Update the send flow to delegate integer parsing and non-negativity
checks to parse_tx_params(parts, 2), then keep only the send-specific amount > 0
validation in the send handler. Make sure the logic stays aligned with the
existing deploy and call paths by reusing parse_tx_params rather than
re-implementing the checks in this block.

Comment thread minichain/state.py Outdated
Comment on lines +141 to +144
gas_used = getattr(tx, 'gas_limit', 0)
gas_refund = tx.gas_limit - gas_used
if gas_refund > 0:
sender['balance'] += (gas_refund * tx.max_fee_per_gas)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== minichain/state.py (around lines 120-170) ==\n'
nl -ba minichain/state.py | sed -n '120,170p'

printf '\n== search for gas_limit / gas_used / deploy handling ==\n'
rg -n "gas_limit|gas_used|deploy|refund" minichain -g '!**/__pycache__/**'

printf '\n== file list for minichain ==\n'
git ls-files minichain

Repository: StabilityNexus/MiniChain

Length of output: 251


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
path = Path('minichain/state.py')
text = path.read_text().splitlines()
for i, line in enumerate(text[119:170], start=120):
    print(f"{i:4d}: {line}")
PY

printf '\n== search for gas_limit / gas_used / deploy handling ==\n'
python3 - <<'PY'
from pathlib import Path
for path in Path('minichain').rglob('*.py'):
    text = path.read_text().splitlines()
    for i, line in enumerate(text, start=1):
        if any(k in line for k in ('gas_limit', 'gas_used', 'deploy', 'refund')):
            print(f"{path}:{i}: {line}")
PY

Repository: StabilityNexus/MiniChain

Length of output: 8633


Remove the dead deploy refund branch
gas_used is set to tx.gas_limit in the deploy path, so gas_refund is always 0 and the refund block can never run. Either meter actual deployment gas here or حذف the dead branch for clarity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@minichain/state.py` around lines 141 - 144, The deploy refund logic in state
processing is dead because gas_used is always set from tx.gas_limit, making
gas_refund permanently zero. Update the deploy handling in state.py around the
tx gas accounting path to either compute real deployment gas usage before
refunding or remove the unreachable gas_refund branch and its sender balance
adjustment for clarity. Use the existing tx, gas_used, gas_refund, and sender
balance update logic to locate and simplify this block.

Comment thread minichain/state.py
Comment on lines +213 to +217
gas_used = getattr(tx, 'gas_limit', 0)
gas_refund = tx.gas_limit - gas_used
if gas_refund > 0:
sender['balance'] += (gas_refund * tx.max_fee_per_gas)
return Receipt(tx.tx_id, status=1, gas_used=gas_used)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '== File context: minichain/state.py ==\n'
nl -ba minichain/state.py | sed -n '170,240p'

printf '\n== Search for gas/refund/receipt logic ==\n'
rg -n "gas_used|gas_refund|gas_limit|max_fee_per_gas|Receipt\(" minichain -S

printf '\n== Locate transaction fields / constructors ==\n'
rg -n "class .*Tx|dataclass.*Tx|gas_limit|max_fee_per_gas" minichain -S

Repository: StabilityNexus/MiniChain

Length of output: 241


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '== File context: minichain/state.py ==\n'
sed -n '170,240p' minichain/state.py

printf '\n== Search for gas/refund/receipt logic ==\n'
rg -n "gas_used|gas_refund|gas_limit|max_fee_per_gas|Receipt\(" minichain -S

printf '\n== Locate transaction classes/constructors ==\n'
rg -n "class .*Tx|dataclass.*Tx|gas_limit|max_fee_per_gas" minichain -S

Repository: StabilityNexus/MiniChain

Length of output: 14009


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,170p' minichain/state.py

Repository: StabilityNexus/MiniChain

Length of output: 6843


Regular transfers never use the refund path

gas_used is set to tx.gas_limit, so gas_refund is always 0 and the refund block can never run. Either meter a fixed intrinsic cost for simple transfers and refund the remainder, or remove the refund logic if full-limit billing is intended.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@minichain/state.py` around lines 213 - 217, The refund logic in the
transaction processing path is unreachable because `gas_used` is being set to
`tx.gas_limit`, which makes `gas_refund` always zero. Update the transfer
handling in the relevant state transition method to either calculate a real
intrinsic gas cost for simple transfers and use that for `gas_used`, or remove
the refund branch entirely if full-limit billing is intended. Use the
`gas_used`, `gas_refund`, and `Receipt` flow in `minichain/state.py` as the
place to adjust this behavior.

@SIDDHANTCOOKIE SIDDHANTCOOKIE changed the title feat: decouple fee into gas_limit and max_fee_per_gas, configurable g… feat: improved tokenomics Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant