├── .clconfig.json
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── 1-bug.yml
│ ├── 2-feature-request.yml
│ └── config.yml
├── PULL_REQUEST_TEMPLATE.md
├── labeler.yml
└── workflows
│ ├── auto-format.yml
│ ├── bsr-push.yml
│ ├── changelog.yml
│ ├── check-licenses.yml
│ ├── codeql-analysis.yml
│ ├── dependencies.yml
│ ├── labeler.yml
│ ├── lint.yml
│ ├── markdown-links.yml
│ ├── proto.yml
│ ├── security.yml
│ ├── semgrep.yml
│ ├── slither.yml
│ ├── solhint.yml
│ ├── solidity-test.yml
│ ├── stale.yml
│ ├── super-linter.yml
│ └── test.yml
├── .gitignore
├── .gitleaks.toml
├── .golangci.yml
├── .markdownlint.yml
├── .markdownlintignore
├── .mergify.yml
├── .protolint.yml
├── .pylintrc
├── .semgrepignore
├── .solhint.json
├── .yamllint
├── CHANGELOG.md
├── LICENSE
├── Makefile
├── README.md
├── SAFU.md
├── SECURITY.md
├── ante
├── cosmos
│ ├── authz.go
│ ├── authz_test.go
│ ├── eip712.go
│ ├── min_gas_price.go
│ ├── min_gas_price_test.go
│ ├── reject_msgs.go
│ ├── setup_test.go
│ └── utils_test.go
├── evm
│ ├── 01_setup_ctx.go
│ ├── 01_setup_ctx_test.go
│ ├── 02_mempool_fee.go
│ ├── 02_mempool_fee_test.go
│ ├── 03_global_fee.go
│ ├── 03_global_fee_test.go
│ ├── 04_validate.go
│ ├── 04_validate_test.go
│ ├── 05_signature_verification.go
│ ├── 06_account_verification.go
│ ├── 06_account_verification_test.go
│ ├── 07_can_transfer.go
│ ├── 07_can_transfer_test.go
│ ├── 08_gas_consume.go
│ ├── 08_gas_consume_test.go
│ ├── 09_increment_sequence.go
│ ├── 09_increment_sequence_test.go
│ ├── 10_gas_wanted.go
│ ├── 10_gas_wanted_test.go
│ ├── 11_emit_event.go
│ ├── ante_test.go
│ ├── eth_benchmark_test.go
│ ├── fee_checker.go
│ ├── fee_checker_test.go
│ ├── fee_market_test.go
│ ├── mono_decorator.go
│ ├── setup_test.go
│ ├── signverify_test.go
│ ├── sigs_test.go
│ ├── suite_test.go
│ ├── utils.go
│ └── utils_test.go
├── interfaces
│ ├── cosmos.go
│ └── evm.go
├── sigverify.go
├── sigverify_test.go
├── testutils
│ └── testutil.go
└── utils_test.go
├── api
└── os
│ ├── crypto
│ └── v1
│ │ └── ethsecp256k1
│ │ └── keys.pulsar.go
│ ├── erc20
│ └── v1
│ │ ├── erc20.pulsar.go
│ │ ├── events.pulsar.go
│ │ ├── genesis.pulsar.go
│ │ ├── msg.go
│ │ ├── query.pulsar.go
│ │ ├── query_grpc.pb.go
│ │ ├── tx.pulsar.go
│ │ └── tx_grpc.pb.go
│ ├── evm
│ └── v1
│ │ ├── access_list_tx.go
│ │ ├── dynamic_fee_tx.go
│ │ ├── events.pulsar.go
│ │ ├── evm.pulsar.go
│ │ ├── genesis.pulsar.go
│ │ ├── legacy_tx.go
│ │ ├── msg.go
│ │ ├── query.pulsar.go
│ │ ├── query_grpc.pb.go
│ │ ├── tx.pulsar.go
│ │ ├── tx_data.go
│ │ └── tx_grpc.pb.go
│ ├── feemarket
│ └── v1
│ │ ├── events.pulsar.go
│ │ ├── feemarket.pulsar.go
│ │ ├── genesis.pulsar.go
│ │ ├── query.pulsar.go
│ │ ├── query_grpc.pb.go
│ │ ├── tx.pulsar.go
│ │ └── tx_grpc.pb.go
│ └── types
│ └── v1
│ ├── dynamic_fee.pulsar.go
│ ├── indexer.pulsar.go
│ └── web3.pulsar.go
├── buf.gen.proto.yaml
├── buf.work.yaml
├── client
├── block
│ ├── block.go
│ └── store.go
├── config.go
├── config_test.go
├── debug
│ └── debug.go
├── export.go
├── import.go
├── keys.go
└── keys
│ ├── add.go
│ └── utils.go
├── cmd
└── config
│ ├── chain_id.go
│ ├── config.go
│ └── opendb.go
├── codecov.yml
├── contracts
├── .gitignore
├── erc20.go
├── hardhat.config.js
├── package-lock.json
├── package.json
├── solidity
│ ├── ERC20MinterBurnerDecimals.json
│ └── ERC20MinterBurnerDecimals.sol
└── utils
│ └── utils.go
├── crypto
├── codec
│ ├── amino.go
│ └── codec.go
├── ethsecp256k1
│ ├── benchmark_test.go
│ ├── ethsecp256k1.go
│ ├── ethsecp256k1_test.go
│ └── keys.pb.go
├── hd
│ ├── algorithm.go
│ ├── algorithm_test.go
│ ├── benchmark_test.go
│ └── utils_test.go
├── keyring
│ └── options.go
└── secp256r1
│ └── verify.go
├── encoding
├── codec
│ └── codec.go
├── config.go
└── config_test.go
├── ethereum
└── eip712
│ ├── domain.go
│ ├── eip712.go
│ ├── eip712_fuzzer_test.go
│ ├── eip712_legacy.go
│ ├── eip712_legacy_test.go
│ ├── eip712_test.go
│ ├── encoding.go
│ ├── encoding_legacy.go
│ ├── message.go
│ ├── preprocess.go
│ ├── preprocess_test.go
│ └── types.go
├── evmOS_repo_header.png
├── example_chain
├── Makefile
├── README.md
├── activators.go
├── ante
│ ├── ante.go
│ ├── cosmos_handler.go
│ ├── evm_benchmark_test.go
│ ├── evm_handler.go
│ ├── handler_options.go
│ ├── handler_options_test.go
│ └── integration_test.go
├── app.go
├── config.go
├── config_testing.go
├── constants.go
├── eips
│ ├── README.md
│ ├── eips.go
│ ├── eips_test.go
│ └── testdata
│ │ ├── Counter.json
│ │ ├── Counter.sol
│ │ ├── CounterFactory.json
│ │ ├── CounterFactory.sol
│ │ └── contracts.go
├── export.go
├── genesis.go
├── go.mod
├── go.sum
├── local_node.sh
├── osd
│ ├── cmd
│ │ └── root.go
│ ├── config
│ │ └── config.go
│ └── main.go
├── precompiles.go
├── test_helpers.go
├── testutil
│ ├── abci.go
│ ├── contract.go
│ ├── eth_setup.go
│ ├── fund.go
│ ├── gas.go
│ └── integration.go
├── token_pair.go
└── upgrades.go
├── go.mod
├── go.sum
├── ibc
├── errors.go
├── module.go
├── module_test.go
├── testing
│ ├── README.md
│ ├── app.go
│ ├── chain.go
│ ├── coordinator.go
│ ├── endpoint.go
│ └── path.go
├── utils.go
└── utils_test.go
├── indexer
├── kv_indexer.go
└── kv_indexer_test.go
├── mlc_config.json
├── precompiles
├── authorization
│ ├── AuthorizationI.sol
│ ├── IICS20Authorization.sol
│ ├── errors.go
│ ├── events.go
│ ├── types.go
│ └── types_test.go
├── bank
│ ├── IBank.sol
│ ├── abi.json
│ ├── bank.go
│ ├── integration_test.go
│ ├── query.go
│ ├── query_test.go
│ ├── setup_test.go
│ ├── testdata
│ │ ├── BankCaller.json
│ │ ├── BankCaller.sol
│ │ └── bank.go
│ ├── types.go
│ └── utils_test.go
├── bech32
│ ├── Bech32I.sol
│ ├── abi.json
│ ├── bech32.go
│ ├── bech32_test.go
│ ├── methods.go
│ ├── methods_test.go
│ └── setup_test.go
├── common
│ ├── Types.sol
│ ├── abi.go
│ ├── errors.go
│ ├── events.go
│ ├── precompile.go
│ ├── types.go
│ └── types_test.go
├── distribution
│ ├── DistributionI.sol
│ ├── abi.json
│ ├── distribution.go
│ ├── distribution_test.go
│ ├── errors.go
│ ├── events.go
│ ├── events_test.go
│ ├── integration_test.go
│ ├── query.go
│ ├── query_test.go
│ ├── setup_test.go
│ ├── tx.go
│ ├── tx_test.go
│ ├── types.go
│ └── utils_test.go
├── erc20
│ ├── IERC20.sol
│ ├── IERC20Metadata.sol
│ ├── IERC20MetadataAllowance.sol
│ ├── abi.json
│ ├── approve.go
│ ├── approve_test.go
│ ├── erc20.go
│ ├── erc20_test.go
│ ├── errors.go
│ ├── errors_test.go
│ ├── events.go
│ ├── events_test.go
│ ├── integration_test.go
│ ├── query.go
│ ├── query_test.go
│ ├── setup_test.go
│ ├── testdata
│ │ ├── ERC20AllowanceCaller.json
│ │ ├── ERC20AllowanceCaller.sol
│ │ ├── ERC20Minter_OpenZeppelinV5.json
│ │ ├── ERC20Minter_OpenZeppelinV5.sol
│ │ ├── ERC20NoMetadata.json
│ │ ├── ERC20NoMetadata.sol
│ │ ├── ERC20TestCaller.json
│ │ ├── ERC20TestCaller.sol
│ │ ├── erc20_allowance_caller.go
│ │ ├── erc20_no_metadata.go
│ │ ├── erc20_test_caller.go
│ │ └── erc20minter_openzeppelinv5.go
│ ├── tx.go
│ ├── tx_test.go
│ ├── types.go
│ ├── types_test.go
│ └── utils_test.go
├── evidence
│ ├── IEvidence.sol
│ ├── abi.json
│ ├── errors.go
│ ├── events.go
│ ├── evidence.go
│ ├── query.go
│ ├── query_test.go
│ ├── setup_test.go
│ ├── tx.go
│ ├── tx_test.go
│ └── types.go
├── gov
│ ├── IGov.sol
│ ├── abi.json
│ ├── errors.go
│ ├── events.go
│ ├── events_test.go
│ ├── gov.go
│ ├── gov_test.go
│ ├── integration_test.go
│ ├── query.go
│ ├── query_test.go
│ ├── setup_test.go
│ ├── testdata
│ │ ├── GovCaller.json
│ │ ├── GovCaller.sol
│ │ └── gov.go
│ ├── tx.go
│ ├── tx_test.go
│ ├── types.go
│ └── utils_test.go
├── ics20
│ ├── ICS20I.sol
│ ├── abi.json
│ ├── approve.go
│ ├── approve_common.go
│ ├── errors.go
│ ├── events.go
│ ├── ics20.go
│ ├── query.go
│ ├── tx.go
│ └── types.go
├── p256
│ ├── integration_test.go
│ ├── p256.go
│ ├── p256_test.go
│ └── setup_test.go
├── slashing
│ ├── ISlashing.sol
│ ├── abi.json
│ ├── events.go
│ ├── events_test.go
│ ├── query.go
│ ├── query_test.go
│ ├── setup_test.go
│ ├── slashing.go
│ ├── tx.go
│ ├── tx_test.go
│ └── types.go
├── staking
│ ├── StakingI.sol
│ ├── abi.json
│ ├── approve.go
│ ├── approve_test.go
│ ├── errors.go
│ ├── events.go
│ ├── events_test.go
│ ├── integration_test.go
│ ├── query.go
│ ├── query_test.go
│ ├── setup_test.go
│ ├── staking.go
│ ├── staking_test.go
│ ├── testdata
│ │ ├── StakingCaller.json
│ │ ├── StakingCaller.sol
│ │ ├── StakingCallerTwo.json
│ │ ├── StakingCallerTwo.sol
│ │ ├── staking_caller.go
│ │ └── staking_caller_two.go
│ ├── tx.go
│ ├── tx_test.go
│ ├── types.go
│ └── utils_test.go
├── testutil
│ ├── contracts
│ │ ├── Counter.json
│ │ ├── Counter.sol
│ │ ├── DistributionCaller.json
│ │ ├── DistributionCaller.sol
│ │ ├── FlashLoan.json
│ │ ├── FlashLoan.sol
│ │ ├── ICounter.sol
│ │ ├── InterchainSender.json
│ │ ├── InterchainSender.sol
│ │ ├── InterchainSenderCaller.json
│ │ ├── InterchainSenderCaller.sol
│ │ ├── Reverter.json
│ │ ├── Reverter.sol
│ │ ├── StakingReverter.json
│ │ ├── StakingReverter.sol
│ │ ├── contracts.go
│ │ ├── counter.go
│ │ ├── distribution_caller.go
│ │ ├── flash_loan.go
│ │ ├── interchain_sender.go
│ │ ├── interchain_sender_caller.go
│ │ ├── reverter.go
│ │ ├── staking_reverter.go
│ │ └── types.go
│ ├── errors.go
│ ├── events.go
│ ├── ibc.go
│ ├── logs.go
│ ├── staking.go
│ └── testing.go
└── werc20
│ ├── IWERC20.sol
│ ├── abi.json
│ ├── events.go
│ ├── events_test.go
│ ├── integration_test.go
│ ├── testdata
│ ├── WEVMOS9.json
│ ├── WEVMOS9TestCaller.json
│ ├── WEVMOS9TestCaller.sol
│ ├── wevmos9.go
│ └── wevmos9_test_caller.go
│ ├── tx.go
│ ├── utils_test.go
│ └── werc20.go
├── proto
├── buf.gen.gogo.yaml
├── buf.gen.pulsar.yaml
├── buf.lock
├── buf.yaml
└── os
│ ├── crypto
│ └── v1
│ │ └── ethsecp256k1
│ │ └── keys.proto
│ ├── erc20
│ └── v1
│ │ ├── erc20.proto
│ │ ├── events.proto
│ │ ├── genesis.proto
│ │ ├── query.proto
│ │ └── tx.proto
│ ├── evm
│ └── v1
│ │ ├── events.proto
│ │ ├── evm.proto
│ │ ├── genesis.proto
│ │ ├── query.proto
│ │ └── tx.proto
│ ├── feemarket
│ └── v1
│ │ ├── events.proto
│ │ ├── feemarket.proto
│ │ ├── genesis.proto
│ │ ├── query.proto
│ │ └── tx.proto
│ └── types
│ └── v1
│ ├── dynamic_fee.proto
│ ├── indexer.proto
│ └── web3.proto
├── rpc
├── apis.go
├── backend
│ ├── account_info.go
│ ├── account_info_test.go
│ ├── backend.go
│ ├── backend_suite_test.go
│ ├── blocks.go
│ ├── blocks_test.go
│ ├── call_tx.go
│ ├── call_tx_test.go
│ ├── chain_info.go
│ ├── chain_info_test.go
│ ├── client_test.go
│ ├── evm_query_client_test.go
│ ├── feemarket_query_client_test.go
│ ├── filters.go
│ ├── filters_test.go
│ ├── mocks
│ │ ├── client.go
│ │ ├── evm_query_client.go
│ │ └── feemarket_query_client.go
│ ├── node_info.go
│ ├── node_info_test.go
│ ├── sign_tx.go
│ ├── sign_tx_test.go
│ ├── tracing.go
│ ├── tracing_test.go
│ ├── tx_info.go
│ ├── tx_info_test.go
│ ├── utils.go
│ └── utils_test.go
├── ethereum
│ └── pubsub
│ │ ├── pubsub.go
│ │ └── pubsub_test.go
├── namespaces
│ └── ethereum
│ │ ├── debug
│ │ ├── api.go
│ │ ├── trace.go
│ │ ├── trace_fallback.go
│ │ └── utils.go
│ │ ├── eth
│ │ ├── api.go
│ │ └── filters
│ │ │ ├── api.go
│ │ │ ├── filter_system.go
│ │ │ ├── filter_system_test.go
│ │ │ ├── filters.go
│ │ │ ├── subscription.go
│ │ │ └── utils.go
│ │ ├── miner
│ │ ├── api.go
│ │ └── unsupported.go
│ │ ├── net
│ │ └── api.go
│ │ ├── personal
│ │ └── api.go
│ │ ├── txpool
│ │ └── api.go
│ │ └── web3
│ │ └── api.go
├── types
│ ├── addrlock.go
│ ├── block.go
│ ├── block_test.go
│ ├── events.go
│ ├── events_test.go
│ ├── query_client.go
│ ├── types.go
│ └── utils.go
└── websockets.go
├── scripts
├── compile_smart_contracts
│ ├── README.md
│ ├── compile_smart_contracts.py
│ ├── test_compile_smart_contracts.py
│ └── testdata
│ │ ├── hardhat.config.js
│ │ ├── package.json
│ │ └── solidity
│ │ └── SimpleContract.sol
├── generate_protos.sh
├── generate_protos_pulsar.sh
└── run-solidity-tests.sh
├── server
├── config
│ ├── config.go
│ ├── config_test.go
│ ├── migration
│ │ ├── migration.go
│ │ └── v0.50-app.toml
│ └── toml.go
├── flags
│ └── flags.go
├── indexer_cmd.go
├── indexer_service.go
├── json_rpc.go
├── start.go
└── util.go
├── shell.nix
├── tests
├── integration
│ └── ledger
│ │ ├── evmosd_suite_test.go
│ │ ├── ledger_test.go
│ │ └── mocks
│ │ ├── AccountRetriever.go
│ │ ├── SECP256K1.go
│ │ ├── registry.go
│ │ └── tendermint.go
└── solidity
│ ├── .gitattributes
│ ├── .gitignore
│ ├── init-node.sh
│ ├── package.json
│ ├── suites
│ ├── basic
│ │ ├── contracts
│ │ │ ├── Counter.sol
│ │ │ ├── EventTest.sol
│ │ │ └── Storage.sol
│ │ ├── package.json
│ │ ├── test
│ │ │ ├── .gitkeep
│ │ │ ├── counter.js
│ │ │ ├── events.js
│ │ │ ├── revert.js
│ │ │ └── storage.js
│ │ └── truffle-config.js
│ ├── eip1559
│ │ ├── package.json
│ │ ├── test
│ │ │ └── eip1559.js
│ │ └── truffle-config.js
│ ├── exception
│ │ ├── contracts
│ │ │ ├── TestRevert.sol
│ │ │ └── test
│ │ │ │ └── Migrations.sol
│ │ ├── migrations
│ │ │ └── 1_initial_migration.js
│ │ ├── package.json
│ │ ├── test
│ │ │ ├── .gitkeep
│ │ │ └── revert.js
│ │ └── truffle-config.js
│ ├── opcode
│ │ ├── contracts
│ │ │ ├── Migrations.sol
│ │ │ └── OpCodes.sol
│ │ ├── migrations
│ │ │ ├── 1_initial_migration.js
│ │ │ └── 2_opCodes_migration.js
│ │ ├── package.json
│ │ ├── test
│ │ │ └── opCodes.js
│ │ └── truffle-config.js
│ └── precompiles
│ │ ├── contracts
│ │ └── .gitkeep
│ │ ├── hardhat.config.js
│ │ ├── package.json
│ │ └── test
│ │ └── staking.js
│ ├── test-helper.js
│ └── yarn.lock
├── testutil
├── ante.go
├── constants
│ ├── constants.go
│ └── constants_test.go
├── fund.go
├── integration
│ ├── common
│ │ ├── factory
│ │ │ ├── base.go
│ │ │ ├── distribution.go
│ │ │ ├── factory.go
│ │ │ ├── fund.go
│ │ │ ├── helper.go
│ │ │ ├── sign.go
│ │ │ ├── staking.go
│ │ │ └── types.go
│ │ ├── grpc
│ │ │ ├── account.go
│ │ │ ├── authz.go
│ │ │ ├── bank.go
│ │ │ ├── distribution.go
│ │ │ ├── grpc.go
│ │ │ └── staking.go
│ │ └── network
│ │ │ └── network.go
│ ├── ibc
│ │ ├── chain
│ │ │ └── chain.go
│ │ └── coordinator
│ │ │ ├── coordinator.go
│ │ │ ├── types.go
│ │ │ └── utils.go
│ └── os
│ │ ├── factory
│ │ ├── broadcast.go
│ │ ├── build.go
│ │ ├── factory.go
│ │ ├── helpers.go
│ │ ├── sign.go
│ │ └── types.go
│ │ ├── grpc
│ │ ├── evm.go
│ │ ├── feemarket.go
│ │ ├── gov.go
│ │ └── grpc.go
│ │ ├── keyring
│ │ └── keyring.go
│ │ ├── network
│ │ ├── abci.go
│ │ ├── amounts.go
│ │ ├── chain_id_modifiers.go
│ │ ├── clients.go
│ │ ├── coins.go
│ │ ├── config.go
│ │ ├── config_test.go
│ │ ├── example_contracts.go
│ │ ├── ibc.go
│ │ ├── network.go
│ │ ├── setup.go
│ │ └── unit_network.go
│ │ └── utils
│ │ ├── bank.go
│ │ ├── bank_test.go
│ │ ├── contracts.go
│ │ ├── erc20.go
│ │ ├── events.go
│ │ ├── evm.go
│ │ ├── evm_test.go
│ │ ├── genesis.go
│ │ ├── gov.go
│ │ ├── params.go
│ │ ├── staking.go
│ │ ├── types.go
│ │ └── unit.go
├── network
│ ├── doc.go
│ ├── network.go
│ ├── network_test.go
│ └── util.go
├── pair.go
├── setup.go
├── staking_rewards.go
├── statedb.go
└── tx
│ ├── cosmos.go
│ ├── eip712.go
│ ├── eth.go
│ └── signer.go
├── tox.ini
├── types
├── block.go
├── chain_id.go
├── chain_id_test.go
├── codec.go
├── dynamic_fee.go
├── dynamic_fee.pb.go
├── errors.go
├── gasmeter.go
├── genesis.go
├── hdpath.go
├── indexer.go
├── indexer.pb.go
├── int.go
├── power.go
├── protocol.go
├── validation.go
├── validation_test.go
└── web3.pb.go
├── utils
├── eth
│ └── eth.go
├── utils.go
└── utils_test.go
├── version
└── version.go
├── wallets
├── accounts
│ └── accounts.go
├── ledger
│ ├── ledger.go
│ ├── ledger_suite_test.go
│ ├── ledger_test.go
│ ├── mocks
│ │ └── wallet.go
│ └── wallet_test.go
└── usbwallet
│ ├── hub.go
│ ├── ledger.go
│ └── wallet.go
└── x
├── erc20
├── client
│ └── cli
│ │ ├── metadata
│ │ ├── coin_metadata_test.json
│ │ ├── coins_metadata_test.json
│ │ └── invalid_metadata_test.json
│ │ ├── query.go
│ │ └── tx.go
├── genesis.go
├── genesis_test.go
├── ibc_middleware.go
├── keeper
│ ├── dynamic_precompiles.go
│ ├── dynamic_precompiles_test.go
│ ├── erc20_utils_test.go
│ ├── evm.go
│ ├── evm_test.go
│ ├── grpc_query.go
│ ├── grpc_query_test.go
│ ├── ibc_callbacks.go
│ ├── ibc_callbacks_test.go
│ ├── integration_test.go
│ ├── keeper.go
│ ├── mint.go
│ ├── mint_test.go
│ ├── msg_server.go
│ ├── msg_server_test.go
│ ├── params.go
│ ├── params_test.go
│ ├── precompiles.go
│ ├── precompiles_test.go
│ ├── proposals.go
│ ├── proposals_test.go
│ ├── setup_test.go
│ ├── testdata
│ │ ├── ERC20DirectBalanceManipulation.json
│ │ ├── ERC20DirectBalanceManipulation.sol
│ │ ├── ERC20MaliciousDelayed.json
│ │ ├── ERC20MaliciousDelayed.sol
│ │ ├── erc20DirectBalanceManipulation.go
│ │ └── erc20maliciousdelayed.go
│ ├── token_pairs.go
│ ├── token_pairs_test.go
│ └── utils_test.go
├── module.go
└── types
│ ├── codec.go
│ ├── constants.go
│ ├── erc20.pb.go
│ ├── errors.go
│ ├── events.go
│ ├── events.pb.go
│ ├── evm.go
│ ├── evm_test.go
│ ├── genesis.go
│ ├── genesis.pb.go
│ ├── genesis_test.go
│ ├── interfaces.go
│ ├── keys.go
│ ├── mocks
│ ├── BankKeeper.go
│ ├── EVMKeeper.go
│ └── README.md
│ ├── msg.go
│ ├── msg_test.go
│ ├── params.go
│ ├── params_test.go
│ ├── proposal.go
│ ├── proposal_test.go
│ ├── query.pb.go
│ ├── query.pb.gw.go
│ ├── token_pair.go
│ ├── token_pair_test.go
│ ├── tx.pb.go
│ ├── tx.pb.gw.go
│ ├── utils.go
│ └── utils_test.go
├── evm
├── ante
│ ├── ctx.go
│ ├── ctx_test.go
│ └── suite_test.go
├── client
│ └── cli
│ │ ├── query.go
│ │ ├── tx.go
│ │ ├── utils.go
│ │ └── utils_test.go
├── core
│ ├── core
│ │ └── utils.go
│ ├── logger
│ │ ├── access_list_tracer.go
│ │ ├── logger.go
│ │ └── logger_json.go
│ ├── tracers
│ │ ├── js
│ │ │ ├── bigint.go
│ │ │ ├── goja.go
│ │ │ ├── internal
│ │ │ │ └── tracers
│ │ │ │ │ ├── 4byte_tracer_legacy.js
│ │ │ │ │ ├── bigram_tracer.js
│ │ │ │ │ ├── call_tracer_legacy.js
│ │ │ │ │ ├── evmdis_tracer.js
│ │ │ │ │ ├── noop_tracer_legacy.js
│ │ │ │ │ ├── opcount_tracer.js
│ │ │ │ │ ├── prestate_tracer_legacy.js
│ │ │ │ │ ├── tracers.go
│ │ │ │ │ ├── trigram_tracer.js
│ │ │ │ │ └── unigram_tracer.js
│ │ │ └── tracer_test.go
│ │ ├── native
│ │ │ ├── 4byte.go
│ │ │ ├── call.go
│ │ │ ├── noop.go
│ │ │ ├── prestate.go
│ │ │ ├── revertreason.go
│ │ │ └── tracer.go
│ │ └── tracers.go
│ └── vm
│ │ ├── analysis.go
│ │ ├── analysis_test.go
│ │ ├── common.go
│ │ ├── contract.go
│ │ ├── contracts.go
│ │ ├── contracts_test.go
│ │ ├── custom_eip.go
│ │ ├── custom_eip_test.go
│ │ ├── custom_eip_testing.go
│ │ ├── doc.go
│ │ ├── eips.go
│ │ ├── errors.go
│ │ ├── evm.go
│ │ ├── gas.go
│ │ ├── gas_table.go
│ │ ├── gas_table_test.go
│ │ ├── instructions.go
│ │ ├── instructions_test.go
│ │ ├── interface.go
│ │ ├── interpreter.go
│ │ ├── interpreter_test.go
│ │ ├── jump_table.go
│ │ ├── jump_table_test.go
│ │ ├── logger.go
│ │ ├── memory.go
│ │ ├── memory_table.go
│ │ ├── opcode_hooks.go
│ │ ├── opcodes.go
│ │ ├── operations_acl.go
│ │ ├── stack.go
│ │ ├── stack_table.go
│ │ └── testdata
│ │ ├── precompiles
│ │ ├── blake2F.json
│ │ ├── blsG1Add.json
│ │ ├── blsG1Mul.json
│ │ ├── blsG1MultiExp.json
│ │ ├── blsG2Add.json
│ │ ├── blsG2Mul.json
│ │ ├── blsG2MultiExp.json
│ │ ├── blsMapG1.json
│ │ ├── blsMapG2.json
│ │ ├── blsPairing.json
│ │ ├── bn256Add.json
│ │ ├── bn256Pairing.json
│ │ ├── bn256ScalarMul.json
│ │ ├── ecRecover.json
│ │ ├── fail-blake2f.json
│ │ ├── fail-blsG1Add.json
│ │ ├── fail-blsG1Mul.json
│ │ ├── fail-blsG1MultiExp.json
│ │ ├── fail-blsG2Add.json
│ │ ├── fail-blsG2Mul.json
│ │ ├── fail-blsG2MultiExp.json
│ │ ├── fail-blsMapG1.json
│ │ ├── fail-blsMapG2.json
│ │ ├── fail-blsPairing.json
│ │ ├── modexp.json
│ │ └── modexp_eip2565.json
│ │ ├── testcases_add.json
│ │ ├── testcases_and.json
│ │ ├── testcases_byte.json
│ │ ├── testcases_div.json
│ │ ├── testcases_eq.json
│ │ ├── testcases_exp.json
│ │ ├── testcases_gt.json
│ │ ├── testcases_lt.json
│ │ ├── testcases_mod.json
│ │ ├── testcases_mul.json
│ │ ├── testcases_or.json
│ │ ├── testcases_sar.json
│ │ ├── testcases_sdiv.json
│ │ ├── testcases_sgt.json
│ │ ├── testcases_shl.json
│ │ ├── testcases_shr.json
│ │ ├── testcases_signext.json
│ │ ├── testcases_slt.json
│ │ ├── testcases_smod.json
│ │ ├── testcases_sub.json
│ │ └── testcases_xor.json
├── genesis.go
├── genesis_test.go
├── keeper
│ ├── abci.go
│ ├── abci_test.go
│ ├── benchmark_test.go
│ ├── block_proposer.go
│ ├── call_evm.go
│ ├── call_evm_test.go
│ ├── config.go
│ ├── fees.go
│ ├── fees_test.go
│ ├── gas.go
│ ├── grpc_query.go
│ ├── grpc_query_test.go
│ ├── integration_test.go
│ ├── keeper.go
│ ├── keeper_test.go
│ ├── msg_server.go
│ ├── msg_server_test.go
│ ├── params.go
│ ├── params_benchmark_test.go
│ ├── params_test.go
│ ├── precompiles.go
│ ├── setup_test.go
│ ├── state_transition.go
│ ├── state_transition_benchmark_test.go
│ ├── state_transition_test.go
│ ├── statedb.go
│ ├── statedb_benchmark_test.go
│ ├── statedb_test.go
│ ├── static_precompiles.go
│ ├── testdata
│ │ ├── ERC20Contract.json
│ │ ├── TestMessageCall.json
│ │ └── contracts.go
│ ├── utils.go
│ └── utils_test.go
├── module.go
├── statedb
│ ├── access_list.go
│ ├── config.go
│ ├── integration_test.go
│ ├── interfaces.go
│ ├── journal.go
│ ├── mock_test.go
│ ├── state_object.go
│ ├── statedb.go
│ └── statedb_test.go
├── types
│ ├── access_list.go
│ ├── access_list_test.go
│ ├── access_list_tx.go
│ ├── access_list_tx_test.go
│ ├── call.go
│ ├── chain_config.go
│ ├── chain_config_test.go
│ ├── codec.go
│ ├── codec_test.go
│ ├── compiled_contract.go
│ ├── compiled_contract_test.go
│ ├── config.go
│ ├── config_testing.go
│ ├── configurator.go
│ ├── configurator_test.go
│ ├── denom.go
│ ├── denom_config.go
│ ├── denom_config_testing.go
│ ├── dynamic_fee_tx.go
│ ├── dynamic_fee_tx_test.go
│ ├── errors.go
│ ├── events.go
│ ├── events.pb.go
│ ├── evm.pb.go
│ ├── genesis.go
│ ├── genesis.pb.go
│ ├── genesis_test.go
│ ├── interfaces.go
│ ├── key.go
│ ├── legacy_tx.go
│ ├── legacy_tx_test.go
│ ├── logs.go
│ ├── logs_test.go
│ ├── msg.go
│ ├── msg_test.go
│ ├── opcodes_hooks.go
│ ├── params.go
│ ├── params_legacy.go
│ ├── params_test.go
│ ├── permissions.go
│ ├── permissions_test.go
│ ├── precompiles.go
│ ├── query.go
│ ├── query.pb.go
│ ├── query.pb.gw.go
│ ├── scaling.go
│ ├── scaling_test.go
│ ├── storage.go
│ ├── storage_test.go
│ ├── testdata
│ │ └── SimpleContractHardhat.json
│ ├── tracer.go
│ ├── tracer_test.go
│ ├── tx.go
│ ├── tx.pb.go
│ ├── tx.pb.gw.go
│ ├── tx_args.go
│ ├── tx_args_test.go
│ ├── tx_data.go
│ ├── tx_data_test.go
│ ├── tx_types.go
│ ├── utils.go
│ └── utils_test.go
└── wrappers
│ ├── README.md
│ ├── bank.go
│ ├── bank_test.go
│ ├── feemarket.go
│ ├── feemarket_test.go
│ └── testutil
│ └── mock.go
├── feemarket
├── client
│ └── cli
│ │ └── query.go
├── genesis.go
├── keeper
│ ├── abci.go
│ ├── abci_test.go
│ ├── eip1559.go
│ ├── eip1559_test.go
│ ├── grpc_query.go
│ ├── grpc_query_test.go
│ ├── integration_test.go
│ ├── keeper.go
│ ├── keeper_test.go
│ ├── msg_server.go
│ ├── msg_server_test.go
│ ├── params.go
│ ├── params_test.go
│ └── setup_test.go
├── module.go
└── types
│ ├── codec.go
│ ├── events.go
│ ├── events.pb.go
│ ├── feemarket.pb.go
│ ├── genesis.go
│ ├── genesis.pb.go
│ ├── genesis_test.go
│ ├── interfaces.go
│ ├── keys.go
│ ├── msg.go
│ ├── msg_test.go
│ ├── params.go
│ ├── params_test.go
│ ├── query.pb.go
│ ├── query.pb.gw.go
│ ├── tx.pb.go
│ └── tx.pb.gw.go
└── ibc
└── transfer
├── ibc_module.go
├── keeper
├── keeper.go
├── keeper_test.go
├── msg_server.go
└── msg_server_test.go
├── module.go
└── types
├── channels.go
└── interfaces.go
/.clconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "categories": [
3 | "all",
4 | "ante",
5 | "bank-precompile",
6 | "ci",
7 | "cli",
8 | "contracts",
9 | "deps",
10 | "dist-precompile",
11 | "eip-712",
12 | "erc20",
13 | "erc20-precompile",
14 | "evm",
15 | "feemarket",
16 | "ibc",
17 | "ics20-precompile",
18 | "precompiles",
19 | "proto",
20 | "rpc",
21 | "server",
22 | "staking-precompile",
23 | "tests",
24 | "types"
25 | ],
26 | "change_types": {
27 | "API Breaking": "feat-api",
28 | "Bug Fixes": "fix",
29 | "Improvements": "imp",
30 | "State Machine Breaking": "feat-smb"
31 | },
32 | "expected_spellings": {
33 | "ABI": "abi",
34 | "API": "api",
35 | "CI": "ci",
36 | "CLI": "cli",
37 | "Cosmos SDK": "cosmos[\\s-]*sdk",
38 | "EIP-712": "eip[\\s-]*712",
39 | "ERC-20": "erc[\\s-]*20",
40 | "EVM": "evm",
41 | "IBC": "ibc",
42 | "ICS": "ics",
43 | "ICS-20": "ics[\\s-]*20",
44 | "OS": "os",
45 | "PR": "pr",
46 | "RPC": "rpc",
47 | "SDK": "sdk"
48 | },
49 | "legacy_version": null,
50 | "target_repo": "https://github.com/evmos/os"
51 | }
52 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # CODEOWNERS: https://help.github.com/articles/about-codeowners/
2 |
3 | # Primary (global) repo maintainers
4 | * @evmos/core-engineering
5 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 | Closes: #XXXX
11 |
12 | ---
13 |
14 | ## Author Checklist
15 |
16 | **All** items are required. Please add a note to the item if the item is not applicable and
17 | please add links to any relevant follow up issues.
18 |
19 | I have...
20 |
21 | - [ ] tackled an existing issue or discussed with a team member
22 | - [ ] left instructions on how to review the changes
23 | - [ ] targeted the `main` branch
24 |
25 | ## Reviewers Checklist
26 |
27 | **All** items are required.
28 | Please add a note if the item is not applicable
29 | and please add your handle next to the items reviewed
30 | if you only reviewed selected items.
31 |
32 | I have...
33 |
34 | - [ ] added a relevant changelog entry to the `Unreleased` section in `CHANGELOG.md`
35 | - [ ] confirmed all author checklist items have been addressed
36 | - [ ] confirmed that this PR does not change production code
37 | - [ ] reviewed content
38 | - [ ] tested instructions (if applicable)
39 | - [ ] confirmed all CI checks have passed
40 |
--------------------------------------------------------------------------------
/.github/labeler.yml:
--------------------------------------------------------------------------------
1 | proto:
2 | - changed-files:
3 | - any-glob-to-any-file: [
4 | "proto/**/*",
5 | "**/*.pb.go",
6 | "**/*.pb.gw.go"
7 | ]
8 | types:
9 | - changed-files:
10 | - any-glob-to-any-file: [
11 | "types/**/*",
12 | ]
13 | build:
14 | - changed-files:
15 | - any-glob-to-any-file: [
16 | "Makefile",
17 | "Dockerfile",
18 | "docker-compose.yml",
19 | "scripts/*",
20 | "config.yml",
21 | ]
22 | CI:
23 | - changed-files:
24 | - any-glob-to-any-file: [
25 | ".github/**/*",
26 | ".mergify.yml",
27 | ".golangci.yml",
28 | "buf.yaml",
29 | ]
30 | CLI:
31 | - changed-files:
32 | - any-glob-to-any-file: [
33 | "client/**/*",
34 | "x/*/client/**/*",
35 | ]
36 | tests:
37 | - changed-files:
38 | - any-glob-to-any-file: [
39 | "tests/**/*",
40 | "testutil/**/*",
41 | "**/*_test.go",
42 | ]
43 | contracts:
44 | - changed-files:
45 | - any-glob-to-any-file: [
46 | "contracts/**/*",
47 | "*.sol",
48 | ]
49 | precompile:
50 | - changed-files:
51 | - any-glob-to-any-file: [
52 | "precompiles/**/*",
53 | ]
54 | release:
55 | - base-branch: "^release/"
56 | feature:
57 | - head-branch: "^feat/"
58 |
--------------------------------------------------------------------------------
/.github/workflows/auto-format.yml:
--------------------------------------------------------------------------------
1 | name: Auto Format
2 |
3 | on:
4 | pull_request:
5 |
6 | permissions: read-all
7 |
8 | jobs:
9 | format-code:
10 | runs-on: ubuntu-latest
11 |
12 | permissions:
13 | contents: write
14 |
15 | steps:
16 | # Checkout repository
17 | - uses: actions/checkout@v4
18 | with:
19 | token: ${{ secrets.E2E_PAT }}
20 |
21 | # Install shell formatter
22 | - run: sudo apt-get install -y shfmt
23 |
24 | # Set up Go
25 | - uses: actions/setup-go@v5
26 | with:
27 | go-version: "1.22"
28 | check-latest: true
29 |
30 | # Install Go formatter
31 | - run: go install mvdan.cc/gofumpt@latest
32 |
33 | # Set up Python
34 | - uses: actions/setup-python@v5
35 | with:
36 | python-version: "3.10"
37 |
38 | # Install Python formatters
39 | - run: pip install black isort
40 |
41 | # Run the combined format command
42 | - run: make format
43 |
44 | # Commit formatted files if necessary
45 | - uses: stefanzweifel/git-auto-commit-action@v5
46 | with:
47 | commit_message: run make format
48 |
--------------------------------------------------------------------------------
/.github/workflows/bsr-push.yml:
--------------------------------------------------------------------------------
1 | name: Push to Buf Schema Registry
2 | # This workflow runs when a new version tag is pushed to the repository.
3 | # It then pushes the Protobuf files corresponding to that tag on to the
4 | # Buf Schema Registry at https://buf.build/evmos/os
5 | on:
6 | push:
7 | tags:
8 | - "v*.*.*"
9 | permissions: read-all
10 |
11 | jobs:
12 | push:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - uses: bufbuild/buf-setup-action@v1.50.0
17 | # Push evmOS protos to the Buf Schema Registry
18 | - uses: bufbuild/buf-push-action@v1.2.0
19 | with:
20 | input: ./proto
21 | buf_token: ${{ secrets.BUF_TOKEN }}
22 |
--------------------------------------------------------------------------------
/.github/workflows/changelog.yml:
--------------------------------------------------------------------------------
1 | name: Changelog Linter
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - main
7 | - release/**
8 | permissions: read-all
9 |
10 | jobs:
11 | check_diff:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - name: Check Changelog for changes
15 | uses: tarides/changelog-check-action@v3
16 | with:
17 | changelog: CHANGELOG.md
18 |
19 | lint_changelog:
20 | runs-on: ubuntu-latest
21 |
22 | steps:
23 | - name: Check out the repository
24 | uses: actions/checkout@v4
25 |
26 | - name: Run changelog linter
27 | uses: MalteHerrmann/changelog-lint-action@0918ef12e6dc06adce0743e1c6c13707a7c20323
28 |
--------------------------------------------------------------------------------
/.github/workflows/check-licenses.yml:
--------------------------------------------------------------------------------
1 | name: Check Licenses
2 | on:
3 | pull_request
4 |
5 | permissions: read-all
6 |
7 | jobs:
8 | check-licenses:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 | - uses: technote-space/get-diff-action@v6.1.2
13 | id: git_diff
14 | with:
15 | PATTERNS: |
16 | **/**.go
17 | **/**.proto
18 | - run: |
19 | make check-licenses
20 | if: env.GIT_DIFF
21 |
--------------------------------------------------------------------------------
/.github/workflows/dependencies.yml:
--------------------------------------------------------------------------------
1 | name: "Dependency Review"
2 | on: pull_request
3 |
4 | permissions: read-all
5 |
6 | jobs:
7 | dependency-review:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/setup-go@v5
11 | with:
12 | go-version: '1.22'
13 | check-latest: true
14 | - name: "Checkout Repository"
15 | uses: actions/checkout@v4
16 | - uses: technote-space/get-diff-action@v6.1.2
17 | with:
18 | PATTERNS: |
19 | **/**.go
20 | go.mod
21 | go.sum
22 | *.toml
23 | - name: "Dependency Review"
24 | uses: actions/dependency-review-action@v4
25 | if: env.GIT_DIFF
26 | - name: "Go vulnerability check"
27 | run: make vulncheck
28 | if: env.GIT_DIFF
29 |
--------------------------------------------------------------------------------
/.github/workflows/labeler.yml:
--------------------------------------------------------------------------------
1 | name: "Pull Request Labeler"
2 | on:
3 | pull_request:
4 | permissions: read-all
5 |
6 | jobs:
7 | triage:
8 | runs-on: ubuntu-latest
9 | permissions:
10 | pull-requests: write # For reading the PR and adding the label
11 | steps:
12 | - uses: actions/labeler@v5
13 | with:
14 | repo-token: "${{ secrets.GITHUB_TOKEN }}"
15 |
--------------------------------------------------------------------------------
/.github/workflows/markdown-links.yml:
--------------------------------------------------------------------------------
1 | name: Check Markdown links
2 | on:
3 | pull_request:
4 | branches:
5 | - main
6 | - release/**
7 | permissions: read-all
8 |
9 | jobs:
10 | markdown-link-check:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 | - uses: technote-space/get-diff-action@v6.1.2
15 | with:
16 | PATTERNS: |
17 | **.md
18 | - uses: gaurav-nelson/github-action-markdown-link-check@master
19 | with:
20 | check-modified-files-only: "yes"
21 | use-quiet-mode: "yes"
22 | base-branch: "main"
23 | config-file: "mlc_config.json"
24 | if: env.GIT_DIFF
25 |
--------------------------------------------------------------------------------
/.github/workflows/proto.yml:
--------------------------------------------------------------------------------
1 | name: Protobuf
2 | # Protobuf runs buf (https://buf.build/) lint and check-breakage
3 | # This workflow is only run when a .proto file has been changed
4 | on:
5 | pull_request:
6 | paths:
7 | - "proto/**"
8 |
9 | permissions: read-all
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-latest
14 | permissions:
15 | contents: write
16 | steps:
17 | - uses: actions/checkout@v4
18 | - uses: technote-space/get-diff-action@v6.1.2
19 | id: git_diff
20 | with:
21 | PATTERNS: |
22 | **/**.proto
23 | **/buf.yaml
24 | buf.work.yaml
25 | buf.gen.yaml
26 | - run: |
27 | make proto-gen
28 | if: env.GIT_DIFF
29 |
30 | lint:
31 | runs-on: ubuntu-latest
32 | timeout-minutes: 5
33 | steps:
34 | - uses: actions/checkout@v4
35 | - uses: bufbuild/buf-setup-action@v1.50.0
36 | - uses: bufbuild/buf-lint-action@v1
37 | with:
38 | input: "proto"
39 |
40 | break-check:
41 | runs-on: ubuntu-latest
42 | steps:
43 | - uses: actions/checkout@v4
44 | - uses: bufbuild/buf-setup-action@v1.50.0
45 | - uses: bufbuild/buf-breaking-action@v1
46 | with:
47 | input: "proto"
48 | against: "https://github.com/${{ github.repository }}.git#branch=${{ github.event.pull_request.base.ref }},ref=HEAD~1,subdir=proto"
49 |
--------------------------------------------------------------------------------
/.github/workflows/security.yml:
--------------------------------------------------------------------------------
1 | name: Run Gosec
2 | on:
3 | pull_request:
4 | permissions: read-all
5 |
6 | jobs:
7 | Gosec:
8 | permissions:
9 | security-events: write
10 |
11 | runs-on: ubuntu-latest
12 | env:
13 | GO111MODULE: on
14 | steps:
15 | - name: Checkout Source
16 | uses: actions/checkout@v4
17 | - name: Get Diff
18 | uses: technote-space/get-diff-action@v6.1.2
19 | with:
20 | PATTERNS: |
21 | **/*.go
22 | go.mod
23 | go.sum
24 | *.toml
25 | - name: Run Gosec Security Scanner
26 | uses: cosmos/gosec@master
27 | with:
28 | # we let the report trigger content trigger a failure using the GitHub Security features.
29 | args: "-no-fail -fmt sarif -out results.sarif ./..."
30 | if: "env.GIT_DIFF_FILTERED != ''"
31 | - name: Upload SARIF file
32 | uses: github/codeql-action/upload-sarif@v3
33 | with:
34 | # Path to SARIF file relative to the root of the repository
35 | sarif_file: results.sarif
36 | if: "env.GIT_DIFF_FILTERED != ''"
37 |
--------------------------------------------------------------------------------
/.github/workflows/semgrep.yml:
--------------------------------------------------------------------------------
1 | name: Semgrep
2 | on:
3 | # Scan changed files in PRs, block on new issues only (existing issues ignored)
4 | pull_request:
5 |
6 | permissions: read-all
7 |
8 | jobs:
9 | # Update from: https://semgrep.dev/docs/semgrep-ci/sample-ci-configs/#github-actions [removing GH Security Dashboard]
10 | semgrep:
11 | name: Scan
12 | runs-on: ubuntu-latest
13 | container:
14 | image: returntocorp/semgrep
15 | if: (github.actor != 'dependabot[bot]')
16 | steps:
17 | - name: Permission issue fix
18 | run: git config --global --add safe.directory /__w/os/os
19 | - uses: actions/checkout@v4
20 | - name: Get Diff
21 | uses: technote-space/get-diff-action@v6.1.2
22 | with:
23 | PATTERNS: |
24 | **/*.go
25 | **/*.js
26 | **/*.ts
27 | **/*.sol
28 | go.mod
29 | go.sum
30 | *.toml
31 | - uses: actions/checkout@v4
32 | - run: semgrep ci --config=auto
33 | env:
34 | SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
35 | if: "env.GIT_DIFF_FILTERED != ''"
36 |
--------------------------------------------------------------------------------
/.github/workflows/slither.yml:
--------------------------------------------------------------------------------
1 | name: Slither Analysis
2 |
3 | on:
4 | pull_request:
5 | permissions: read-all
6 |
7 | jobs:
8 | analyze:
9 | name: Run Slither
10 | runs-on: ubuntu-latest
11 | permissions:
12 | contents: read
13 | security-events: write
14 | steps:
15 | - name: Checkout repository
16 | uses: actions/checkout@v4
17 | - name: Get Diff
18 | uses: technote-space/get-diff-action@v6.1.2
19 | with:
20 | PATTERNS: |
21 | **/*.sol
22 | - name: Node dependencies Install
23 | run: |
24 | cd contracts && npm i
25 | cp -r node_modules/@openzeppelin .
26 | - name: Run Slither Action
27 | uses: crytic/slither-action@v0.4.0
28 | continue-on-error: true
29 | id: slither
30 | with:
31 | target: contracts/
32 | if: "env.GIT_DIFF"
--------------------------------------------------------------------------------
/.github/workflows/solhint.yml:
--------------------------------------------------------------------------------
1 | name: Solhint
2 | # This workflow is only run when a .sol file has been changed
3 | on:
4 | pull_request:
5 |
6 | permissions: read-all
7 |
8 | jobs:
9 | solhint:
10 | name: runner / solhint
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 | - uses: technote-space/get-diff-action@v6.1.2
15 | id: git_diff
16 | with:
17 | PATTERNS: |
18 | **/**.sol
19 | - uses: actions/setup-node@v4
20 | if: env.GIT_DIFF
21 | - run: npm install -g solhint
22 | if: env.GIT_DIFF
23 | - run: solhint --version
24 | if: env.GIT_DIFF
25 | - run: solhint '**/*.sol'
26 | if: env.GIT_DIFF
27 |
--------------------------------------------------------------------------------
/.github/workflows/solidity-test.yml:
--------------------------------------------------------------------------------
1 | name: Solidity Test
2 | on:
3 | pull_request:
4 | branches:
5 | - main
6 | - release/**
7 | permissions: read-all
8 |
9 | jobs:
10 | test-solidity:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/setup-go@v5
14 | with:
15 | go-version: '1.22'
16 | check-latest: true
17 | - uses: actions/checkout@v4
18 | - uses: technote-space/get-diff-action@v6.1.2
19 | with:
20 | PATTERNS: |
21 | **/**.sol
22 | **/**.go
23 | go.mod
24 | go.sum
25 | *.toml
26 | - name: Test Solidity
27 | run: |
28 | make test-solidity
29 | if: env.GIT_DIFF
30 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: "Close stale issues & pull requests"
2 | on:
3 | schedule:
4 | - cron: "0 0 * * *"
5 | permissions: read-all
6 |
7 | jobs:
8 | stale:
9 | permissions:
10 | pull-requests: write # For reading the PR and adding the label
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/stale@v9
14 | with:
15 | repo-token: ${{ secrets.GITHUB_TOKEN }}
16 | stale-pr-message: "This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days-before-close if no further activity occurs."
17 | stale-issue-message: "This issue is stale because it has been open 45 days with no activity. Remove `Status: Stale` label or comment or this will be closed in 7 days."
18 | days-before-stale: 45
19 | days-before-close: 7
20 | exempt-issue-labels: "Status: Blocked, Type: Bug, pinned, automerge"
21 | exempt-pr-labels: "Status: Blocked, Type: Bug, pinned, automerge"
22 | stale-pr-label: "Status: Stale"
23 | stale-issue-label: "Status: Stale"
24 |
--------------------------------------------------------------------------------
/.github/workflows/super-linter.yml:
--------------------------------------------------------------------------------
1 | # This workflow executes several linters on changed files based on languages used in your code base whenever
2 | # you push a code or open a pull request.
3 | #
4 | # You can adjust the behavior by modifying this file.
5 | # For more information, see:
6 | # https://github.com/github/super-linter
7 | ---
8 | name: Lint Code Base
9 |
10 | on:
11 | pull_request:
12 | permissions: read-all
13 | jobs:
14 | run-lint:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Checkout code
18 | uses: actions/checkout@v4
19 | with:
20 | # Full git history is needed to get a proper list of changed files within `super-linter`
21 | fetch-depth: 0
22 |
23 | - name: Lint Code Base
24 | uses: github/super-linter@v6
25 | env:
26 | LINTER_RULES_PATH: /
27 | YAML_CONFIG_FILE: .yamllint
28 | VALIDATE_ALL_CODEBASE: false
29 | MARKDOWN_CONFIG_FILE: .markdownlint.yml
30 | PROTOBUF_CONFIG_FILE: .protolint.yml
31 | VALIDATE_NATURAL_LANGUAGE: false
32 | VALIDATE_OPENAPI: false
33 | VALIDATE_JAVASCRIPT_STANDARD: false
34 | VALIDATE_JSCPD: false
35 | VALIDATE_GO: false
36 | VALIDATE_GO_MODULES: false
37 | PYTHON_PYLINT_CONFIG_FILE: .pylintrc
38 | DEFAULT_BRANCH: "main"
39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40 | FILTER_REGEX_EXCLUDE: .*.jsonnet
41 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS
2 | .DS_Store
3 | *.swp
4 | *.swo
5 | *.swl
6 | *.swm
7 | *.swn
8 | *.pyc
9 | *.exe
10 | *.exe~
11 | *.dll
12 | *.so
13 | *.dylib
14 | .dccache
15 |
16 | # Testing
17 | coverage.txt
18 | yarn.lock
19 |
20 | # IDE
21 | .idea/
22 | .vscode/
23 | *.iml
24 | *.code-workspace
25 |
26 | # Node.js
27 | **/node_modules
28 |
29 | # OpenZeppelin contracts
30 | contracts/@openzeppelin/*
31 |
32 | # Build files
33 | example_chain/build/
34 |
--------------------------------------------------------------------------------
/.markdownlint.yml:
--------------------------------------------------------------------------------
1 | "default": true
2 | "MD001": false
3 | "MD004": false
4 | "MD007":
5 | "indent": 4
6 | "MD024":
7 | "siblings_only": true
8 | "MD025": false
9 | "MD026":
10 | "punctuation": ".;:"
11 | "MD029": false
12 | "MD033": false
13 | "MD034": false
14 | "MD036": false
15 | "MD040": false
16 | "MD041": false
17 | "MD051": false
18 | "MD049":
19 | "style": "asterisk"
20 | "MD013":
21 | "line_length": 120
22 | "code_blocks": false
23 | "tables": false
24 | "no-hard-tabs": false
25 |
--------------------------------------------------------------------------------
/.markdownlintignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evmos/os/d14323f1cec649ba36b3382a66b3f5159a531ad1/.markdownlintignore
--------------------------------------------------------------------------------
/.mergify.yml:
--------------------------------------------------------------------------------
1 | queue_rules:
2 | - name: default
3 | queue_conditions:
4 | - "#approved-reviews-by>1"
5 | - base=main
6 | - label=automerge
7 | merge_conditions:
8 | - "#approved-reviews-by>1"
9 | merge_method: squash
10 | commit_message_template: |
11 | {{ title }} (#{{ number }})
12 | {{ body }}
13 |
14 | pull_request_rules:
15 | - name: backport patches to v6.0.x branch
16 | conditions:
17 | - base=main
18 | - label=backport/6.0.x
19 | actions:
20 | backport:
21 | branches:
22 | - release/v6.0.x
23 | - name: backport patches to v5.0.x branch
24 | conditions:
25 | - base=main
26 | - label=backport/5.0.x
27 | actions:
28 | backport:
29 | branches:
30 | - release/v5.0.x
31 | - name: backport patches to v4.0.x branch
32 | conditions:
33 | - base=main
34 | - label=backport/4.0.x
35 | actions:
36 | backport:
37 | branches:
38 | - release/v4.0.x
39 | - name: backport patches to v3.0.x branch
40 | conditions:
41 | - base=main
42 | - label=backport/3.0.x
43 | actions:
44 | backport:
45 | branches:
46 | - release/v3.0.x
47 | - name: refactored queue action rule
48 | conditions: []
49 | actions:
50 | queue:
51 |
--------------------------------------------------------------------------------
/.semgrepignore:
--------------------------------------------------------------------------------
1 | # Ignore git items
2 | .gitignore
3 | .git/
4 | :include .gitignore
5 |
6 | # Common large paths
7 | node_modules/
8 | build/
9 | dist/
10 | vendor/
11 | .env/
12 | .venv/
13 | .tox/
14 | *.min.js
15 |
16 | # Ignore proto
17 | *.proto
18 |
19 | # Common test paths
20 | test/
21 | tests/
22 | *_test.go
23 | *.pb.gw.go
24 | *.pb.go
25 |
26 | # Semgrep rules folder
27 | .semgrep
28 |
29 | # Semgrep-action log folder
30 | .semgrep_logs/
31 |
32 | # GETH code
33 | x/evm/core/
34 |
--------------------------------------------------------------------------------
/.solhint.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "solhint:default"
3 | }
4 |
--------------------------------------------------------------------------------
/.yamllint:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | yaml-files:
4 | - '*.yaml'
5 | - '*.yml'
6 | - '.yamllint'
7 |
8 | rules:
9 | braces: enable
10 | brackets: enable
11 | colons: enable
12 | commas: enable
13 | comments:
14 | level: warning
15 | comments-indentation: disable
16 | document-end: disable
17 | document-start: disable
18 | empty-lines: disable
19 | empty-values: disable
20 | float-values: disable
21 | hyphens: enable
22 | indentation: enable
23 | key-duplicates: enable
24 | key-ordering: disable
25 | line-length: disable
26 | new-line-at-end-of-file: enable
27 | new-lines: enable
28 | octal-values: disable
29 | quoted-strings: disable
30 | trailing-spaces: disable
31 | truthy: disable
--------------------------------------------------------------------------------
/ante/cosmos/reject_msgs.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package cosmos
5 |
6 | import (
7 | errorsmod "cosmossdk.io/errors"
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | errortypes "github.com/cosmos/cosmos-sdk/types/errors"
10 | evmtypes "github.com/evmos/os/x/evm/types"
11 | )
12 |
13 | // RejectMessagesDecorator prevents invalid msg types from being executed.
14 | type RejectMessagesDecorator struct{}
15 |
16 | // NewRejectMessagesDecorator creates a new RejectMessagesDecorator.
17 | func NewRejectMessagesDecorator() sdk.AnteDecorator {
18 | return RejectMessagesDecorator{}
19 | }
20 |
21 | // AnteHandle rejects messages that requires ethereum-specific authentication.
22 | // For example `MsgEthereumTx` requires fee to be deducted in the antehandler in
23 | // order to perform the refund.
24 | func (rmd RejectMessagesDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
25 | for _, msg := range tx.GetMsgs() {
26 | if _, ok := msg.(*evmtypes.MsgEthereumTx); ok {
27 | return ctx, errorsmod.Wrapf(
28 | errortypes.ErrInvalidType,
29 | "MsgEthereumTx needs to be contained within a tx with 'ExtensionOptionsEthereumTx' option",
30 | )
31 | }
32 | }
33 | return next(ctx, tx, simulate)
34 | }
35 |
--------------------------------------------------------------------------------
/ante/cosmos/setup_test.go:
--------------------------------------------------------------------------------
1 | package cosmos_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/evmos/os/ante/testutils"
7 | "github.com/stretchr/testify/suite"
8 | )
9 |
10 | type AnteTestSuite struct {
11 | *testutils.AnteTestSuite
12 | }
13 |
14 | func TestAnteTestSuite(t *testing.T) {
15 | baseSuite := new(testutils.AnteTestSuite)
16 | baseSuite.WithLondonHardForkEnabled(true)
17 | baseSuite.WithFeemarketEnabled(true)
18 |
19 | suite.Run(t, &AnteTestSuite{baseSuite})
20 | }
21 |
--------------------------------------------------------------------------------
/ante/evm/02_mempool_fee.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package evm
5 |
6 | import (
7 | errorsmod "cosmossdk.io/errors"
8 | sdkmath "cosmossdk.io/math"
9 | errortypes "github.com/cosmos/cosmos-sdk/types/errors"
10 | )
11 |
12 | // CheckMempoolFee checks if the provided fee is at least as large as the local
13 | // validator's configured value. The fee computation assumes that both price and fee are
14 | // represented in 18 decimals.
15 | func CheckMempoolFee(fee, mempoolMinGasPrice, gasLimit sdkmath.LegacyDec, isLondon bool) error {
16 | if isLondon {
17 | return nil
18 | }
19 |
20 | requiredFee := mempoolMinGasPrice.Mul(gasLimit)
21 |
22 | if fee.LT(requiredFee) {
23 | return errorsmod.Wrapf(
24 | errortypes.ErrInsufficientFee,
25 | "got: %s, minimum required: %s",
26 | fee, requiredFee,
27 | )
28 | }
29 |
30 | return nil
31 | }
32 |
--------------------------------------------------------------------------------
/ante/evm/09_increment_sequence.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package evm
5 |
6 | import (
7 | errorsmod "cosmossdk.io/errors"
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | errortypes "github.com/cosmos/cosmos-sdk/types/errors"
10 | anteinterfaces "github.com/evmos/os/ante/interfaces"
11 | )
12 |
13 | // IncrementNonce increments the sequence of the account.
14 | func IncrementNonce(
15 | ctx sdk.Context,
16 | accountKeeper anteinterfaces.AccountKeeper,
17 | account sdk.AccountI,
18 | txNonce uint64,
19 | ) error {
20 | nonce := account.GetSequence()
21 | // we merged the nonce verification to nonce increment, so when tx includes multiple messages
22 | // with same sender, they'll be accepted.
23 | if txNonce != nonce {
24 | return errorsmod.Wrapf(
25 | errortypes.ErrInvalidSequence,
26 | "invalid nonce; got %d, expected %d", txNonce, nonce,
27 | )
28 | }
29 |
30 | nonce++
31 |
32 | if err := account.SetSequence(nonce); err != nil {
33 | return errorsmod.Wrapf(err, "failed to set sequence to %d", nonce)
34 | }
35 |
36 | accountKeeper.SetAccount(ctx, account)
37 | return nil
38 | }
39 |
--------------------------------------------------------------------------------
/ante/evm/setup_test.go:
--------------------------------------------------------------------------------
1 | package evm_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/evmos/os/ante/testutils"
7 | "github.com/stretchr/testify/suite"
8 | )
9 |
10 | type AnteTestSuite struct {
11 | *testutils.AnteTestSuite
12 | useLegacyEIP712TypedData bool
13 | }
14 |
15 | func TestAnteTestSuite(t *testing.T) {
16 | baseSuite := new(testutils.AnteTestSuite)
17 | baseSuite.WithLondonHardForkEnabled(true)
18 |
19 | suite.Run(t, &AnteTestSuite{
20 | AnteTestSuite: baseSuite,
21 | })
22 |
23 | // Re-run the tests with EIP-712 Legacy encodings to ensure backwards compatibility.
24 | // LegacyEIP712Extension should not be run with current TypedData encodings, since they are not compatible.
25 | suite.Run(t, &AnteTestSuite{
26 | AnteTestSuite: baseSuite,
27 | useLegacyEIP712TypedData: true,
28 | })
29 | }
30 |
--------------------------------------------------------------------------------
/ante/evm/suite_test.go:
--------------------------------------------------------------------------------
1 | package evm_test
2 |
3 | import (
4 | "testing"
5 |
6 | gethtypes "github.com/ethereum/go-ethereum/core/types"
7 | testconstants "github.com/evmos/os/testutil/constants"
8 | "github.com/stretchr/testify/suite"
9 | )
10 |
11 | // EvmAnteTestSuite aims to test all EVM ante handler unit functions.
12 | // NOTE: the suite only holds properties related to global execution parameters
13 | // (what type of tx to run the tests with) not independent tests values.
14 | type EvmAnteTestSuite struct {
15 | suite.Suite
16 |
17 | // To make sure that every tests is run with all the tx types
18 | ethTxType int
19 | chainID string
20 | }
21 |
22 | func TestEvmAnteTestSuite(t *testing.T) {
23 | txTypes := []int{gethtypes.DynamicFeeTxType, gethtypes.LegacyTxType, gethtypes.AccessListTxType}
24 | chainIDs := []string{testconstants.ExampleChainID, testconstants.SixDecimalsChainID}
25 | for _, txType := range txTypes {
26 | for _, chainID := range chainIDs {
27 | suite.Run(t, &EvmAnteTestSuite{
28 | ethTxType: txType,
29 | chainID: chainID,
30 | })
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/ante/interfaces/cosmos.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package interfaces
5 |
6 | import (
7 | "context"
8 |
9 | addresscodec "cosmossdk.io/core/address"
10 | sdk "github.com/cosmos/cosmos-sdk/types"
11 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
12 | )
13 |
14 | type AccountKeeper interface {
15 | NewAccountWithAddress(ctx context.Context, addr sdk.AccAddress) sdk.AccountI
16 | GetModuleAddress(moduleName string) sdk.AccAddress
17 | GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI
18 | SetAccount(ctx context.Context, account sdk.AccountI)
19 | RemoveAccount(ctx context.Context, account sdk.AccountI)
20 | GetParams(ctx context.Context) (params authtypes.Params)
21 | GetSequence(ctx context.Context, addr sdk.AccAddress) (uint64, error)
22 | AddressCodec() addresscodec.Codec
23 | }
24 |
25 | type BankKeeper interface {
26 | GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin
27 | IsSendEnabledCoins(ctx context.Context, coins ...sdk.Coin) error
28 | SendCoins(ctx context.Context, from, to sdk.AccAddress, amt sdk.Coins) error
29 | SendCoinsFromAccountToModule(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
30 | }
31 |
--------------------------------------------------------------------------------
/ante/utils_test.go:
--------------------------------------------------------------------------------
1 | package ante_test
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 |
7 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
8 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
9 | "github.com/evmos/os/ante"
10 | "github.com/evmos/os/crypto/ethsecp256k1"
11 | )
12 |
13 | func generatePubKeysAndSignatures(n int, msg []byte, _ bool) (pubkeys []cryptotypes.PubKey, signatures [][]byte) {
14 | pubkeys = make([]cryptotypes.PubKey, n)
15 | signatures = make([][]byte, n)
16 | for i := 0; i < n; i++ {
17 | privkey, _ := ethsecp256k1.GenerateKey()
18 | pubkeys[i] = privkey.PubKey()
19 | signatures[i], _ = privkey.Sign(msg)
20 | }
21 | return
22 | }
23 |
24 | func expectedGasCostByKeys(pubkeys []cryptotypes.PubKey) uint64 {
25 | cost := uint64(0)
26 | for _, pubkey := range pubkeys {
27 | pubkeyType := strings.ToLower(fmt.Sprintf("%T", pubkey))
28 | switch {
29 | case strings.Contains(pubkeyType, "ed25519"):
30 | cost += authtypes.DefaultSigVerifyCostED25519
31 | case strings.Contains(pubkeyType, "ethsecp256k1"):
32 | cost += ante.Secp256k1VerifyCost
33 | default:
34 | panic("unexpected key type")
35 | }
36 | }
37 | return cost
38 | }
39 |
--------------------------------------------------------------------------------
/api/os/erc20/v1/msg.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package erc20v1
5 |
6 | import (
7 | "fmt"
8 |
9 | "github.com/ethereum/go-ethereum/common"
10 | protov2 "google.golang.org/protobuf/proto"
11 | )
12 |
13 | // GetSigners gets the signer's address from the Ethereum tx signature
14 | func GetSigners(msg protov2.Message) ([][]byte, error) {
15 | msgConvERC20, ok := msg.(*MsgConvertERC20)
16 | if !ok {
17 | return nil, fmt.Errorf("invalid type, expected MsgConvertERC20 and got %T", msg)
18 | }
19 |
20 | // The sender on the msg is a hex address
21 | sender := common.HexToAddress(msgConvERC20.Sender)
22 |
23 | return [][]byte{sender.Bytes()}, nil
24 | }
25 |
--------------------------------------------------------------------------------
/api/os/evm/v1/tx_data.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package evmv1
4 |
5 | import (
6 | "math/big"
7 |
8 | sdkmath "cosmossdk.io/math"
9 | "github.com/ethereum/go-ethereum/common"
10 | ethtypes "github.com/ethereum/go-ethereum/core/types"
11 | "google.golang.org/protobuf/reflect/protoreflect"
12 | )
13 |
14 | var (
15 | _ TxDataV2 = &LegacyTx{}
16 | _ TxDataV2 = &AccessListTx{}
17 | _ TxDataV2 = &DynamicFeeTx{}
18 | )
19 |
20 | // TxDataV2 implements the Ethereum transaction tx structure. It is used
21 | // solely to define the custom logic for getting signers on Ethereum transactions.
22 | type TxDataV2 interface {
23 | GetChainID() *big.Int
24 | AsEthereumData() ethtypes.TxData
25 |
26 | ProtoReflect() protoreflect.Message
27 | }
28 |
29 | // helper function to parse string to bigInt
30 | func stringToBigInt(str string) *big.Int {
31 | if str == "" {
32 | return nil
33 | }
34 | res, ok := sdkmath.NewIntFromString(str)
35 | if !ok {
36 | return nil
37 | }
38 | return res.BigInt()
39 | }
40 |
41 | func stringToAddress(toStr string) *common.Address {
42 | if toStr == "" {
43 | return nil
44 | }
45 | addr := common.HexToAddress(toStr)
46 | return &addr
47 | }
48 |
--------------------------------------------------------------------------------
/buf.gen.proto.yaml:
--------------------------------------------------------------------------------
1 | version: v1
2 |
3 | plugins:
4 |
5 | - name: gocosmos
6 | out: .
7 | opt:
8 | - plugins=interfacetype+grpc
9 |
10 | - name: grpc-gateway
11 | out: .
12 | opt:
13 | - logtostderr=true
14 |
15 | - name: doc
16 | out: ./docs/protocol
17 | opt:
18 | - ./docs/protodoc-markdown.tmpl,proto-docs.md
19 | strategy: all
20 |
--------------------------------------------------------------------------------
/buf.work.yaml:
--------------------------------------------------------------------------------
1 | version: v1
2 | directories:
3 | - proto
4 |
--------------------------------------------------------------------------------
/client/config_test.go:
--------------------------------------------------------------------------------
1 | package client
2 |
3 | import (
4 | "os"
5 | "path/filepath"
6 | "testing"
7 |
8 | "github.com/cosmos/cosmos-sdk/client/flags"
9 | "github.com/spf13/cobra"
10 | )
11 |
12 | func TestInitConfigNonNotExistError(t *testing.T) {
13 | tempDir := t.TempDir()
14 | subDir := filepath.Join(tempDir, "nonPerms")
15 | if err := os.Mkdir(subDir, 0o600); err != nil {
16 | t.Fatalf("Failed to create sub directory: %v", err)
17 | }
18 | cmd := &cobra.Command{}
19 | cmd.PersistentFlags().String(flags.FlagHome, "", "")
20 | if err := cmd.PersistentFlags().Set(flags.FlagHome, subDir); err != nil {
21 | t.Fatalf("Could not set home flag [%T] %v", err, err)
22 | }
23 |
24 | if err := InitConfig(cmd); !os.IsPermission(err) {
25 | t.Fatalf("Failed to catch permissions error, got: [%T] %v", err, err)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/client/keys/utils.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package keys
5 |
6 | import (
7 | "encoding/json"
8 | "fmt"
9 | "io"
10 |
11 | "sigs.k8s.io/yaml"
12 |
13 | "github.com/cosmos/cosmos-sdk/client/keys"
14 | cryptokeyring "github.com/cosmos/cosmos-sdk/crypto/keyring"
15 | )
16 |
17 | // available output formats.
18 | const (
19 | OutputFormatText = "text"
20 | OutputFormatJSON = "json"
21 | )
22 |
23 | type bechKeyOutFn func(k *cryptokeyring.Record) (keys.KeyOutput, error)
24 |
25 | func printKeyringRecord(w io.Writer, k *cryptokeyring.Record, bechKeyOut bechKeyOutFn, output string) error {
26 | ko, err := bechKeyOut(k)
27 | if err != nil {
28 | return err
29 | }
30 |
31 | switch output {
32 | case OutputFormatText:
33 | if err := printTextRecords(w, []keys.KeyOutput{ko}); err != nil {
34 | return err
35 | }
36 |
37 | case OutputFormatJSON:
38 | out, err := json.Marshal(ko)
39 | if err != nil {
40 | return err
41 | }
42 |
43 | if _, err := fmt.Fprintln(w, string(out)); err != nil {
44 | return err
45 | }
46 | }
47 |
48 | return nil
49 | }
50 |
51 | func printTextRecords(w io.Writer, kos []keys.KeyOutput) error {
52 | out, err := yaml.Marshal(&kos)
53 | if err != nil {
54 | return err
55 | }
56 |
57 | if _, err := fmt.Fprintln(w, string(out)); err != nil {
58 | return err
59 | }
60 |
61 | return nil
62 | }
63 |
--------------------------------------------------------------------------------
/cmd/config/chain_id.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package config
5 |
6 | import (
7 | "path/filepath"
8 |
9 | "github.com/cosmos/cosmos-sdk/client/config"
10 | "github.com/spf13/viper"
11 | )
12 |
13 | // GetChainIDFromHome returns the chain ID from the client configuration
14 | // in the given home directory.
15 | func GetChainIDFromHome(home string) (string, error) {
16 | v := viper.New()
17 | v.AddConfigPath(filepath.Join(home, "config"))
18 | v.SetConfigName("client")
19 | v.SetConfigType("toml")
20 |
21 | if err := v.ReadInConfig(); err != nil {
22 | return "", err
23 | }
24 | conf := new(config.ClientConfig)
25 |
26 | if err := v.Unmarshal(conf); err != nil {
27 | return "", err
28 | }
29 |
30 | return conf.ChainID, nil
31 | }
32 |
--------------------------------------------------------------------------------
/cmd/config/config.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package config
5 |
6 | import (
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/evmos/os/types"
9 | )
10 |
11 | // SetBip44CoinType sets the global coin type to be used in hierarchical deterministic wallets.
12 | func SetBip44CoinType(config *sdk.Config) {
13 | config.SetCoinType(types.Bip44CoinType)
14 | config.SetPurpose(sdk.Purpose) // Shared
15 | config.SetFullFundraiserPath(types.BIP44HDPath) //nolint: staticcheck
16 | }
17 |
--------------------------------------------------------------------------------
/cmd/config/opendb.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | //go:build !rocksdb
5 | // +build !rocksdb
6 |
7 | package config
8 |
9 | import (
10 | "path/filepath"
11 |
12 | dbm "github.com/cosmos/cosmos-db"
13 | "github.com/cosmos/cosmos-sdk/server/types"
14 | )
15 |
16 | // OpenDB opens a database based on the specified backend type.
17 | // It takes the home directory where the database data will be stored, along with the backend type.
18 | // It opens a database named "application" using the specified backend type and the data directory.
19 | // It returns the opened database and an error (if any). If the database opens successfully, the error will be nil.
20 | //
21 | // NOTE: this is included in builds without rocksdb.
22 | // When building the binary with rocksdb, the code in 'rocksdb.go' will be included
23 | // instead of this
24 | func OpenDB(_ types.AppOptions, home string, backendType dbm.BackendType) (dbm.DB, error) {
25 | dataDir := filepath.Join(home, "data")
26 | return dbm.NewDB("application", backendType, dataDir)
27 | }
28 |
29 | // OpenReadOnlyDB opens rocksdb backend in read-only mode.
30 | func OpenReadOnlyDB(home string, backendType dbm.BackendType) (dbm.DB, error) {
31 | return OpenDB(nil, home, backendType)
32 | }
33 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | #
2 | # This codecov.yml is the default configuration for
3 | # all repositories on Codecov. You may adjust the settings
4 | # below in your own codecov.yml in your repository.
5 | #
6 | coverage:
7 | precision: 2
8 | round: down
9 | range: 70...100
10 |
11 | status:
12 | # Learn more at https://docs.codecov.io/docs/commit-status
13 | project:
14 | default:
15 | threshold: 1% # allow this much decrease on project
16 | target: 90%
17 | changes: false
18 |
19 | comment:
20 | layout: "reach, diff, files"
21 | behavior: default # update if exists else create new
22 | require_changes: true
23 |
24 | ignore:
25 | - "**/*.md"
26 | - "cmd"
27 | - "client"
28 | - "proto"
29 | - "testutil"
30 | - "**/test_*.go"
31 | - "**/*.pb.go"
32 | - "**/*.pb.gw.go"
33 | - "x/**/module.go"
34 | - "scripts"
35 | - "ibc/testing"
36 | - "version"
37 |
--------------------------------------------------------------------------------
/contracts/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled contracts
2 | artifacts/
3 |
4 | # Cached files
5 | cache/
6 |
7 | # Node modules
8 | node_modules/
9 |
--------------------------------------------------------------------------------
/contracts/erc20.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package contracts
5 |
6 | import (
7 | _ "embed"
8 |
9 | contractutils "github.com/evmos/os/contracts/utils"
10 | evmtypes "github.com/evmos/os/x/evm/types"
11 | )
12 |
13 | var (
14 | // ERC20MinterBurnerDecimalsJSON are the compiled bytes of the ERC20MinterBurnerDecimalsContract
15 | //
16 | //go:embed solidity/ERC20MinterBurnerDecimals.json
17 | ERC20MinterBurnerDecimalsJSON []byte
18 |
19 | // ERC20MinterBurnerDecimalsContract is the compiled erc20 contract
20 | ERC20MinterBurnerDecimalsContract evmtypes.CompiledContract
21 | )
22 |
23 | func init() {
24 | var err error
25 | if ERC20MinterBurnerDecimalsContract, err = contractutils.ConvertHardhatBytesToCompiledContract(
26 | ERC20MinterBurnerDecimalsJSON,
27 | ); err != nil {
28 | panic(err)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/contracts/hardhat.config.js:
--------------------------------------------------------------------------------
1 | /** @type import('hardhat/config').HardhatUserConfig */
2 | module.exports = {
3 | solidity: {
4 | compilers: [
5 | {
6 | version: "0.8.20",
7 | },
8 | // This version is required to compile the werc9 contract.
9 | {
10 | version: "0.4.22",
11 | },
12 | ],
13 | },
14 | paths: {
15 | sources: "./solidity",
16 | },
17 | };
18 |
--------------------------------------------------------------------------------
/contracts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "evmos-contracts",
3 | "version": "2.0.0",
4 | "description": "A collection of smart contracts used in the development of the Evmos blockchain.",
5 | "devDependencies": {
6 | "@openzeppelin/contracts": "^4.9.6",
7 | "hardhat": "^2.22.2"
8 | },
9 | "scripts": {
10 | "test": "echo \"Error: no test specified\" && exit 1"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/evmos/evmos.git"
15 | },
16 | "author": "Evmos Core Team",
17 | "license": "ISC",
18 | "bugs": {
19 | "url": "https://github.com/evmos/evmos/issues"
20 | },
21 | "homepage": "https://github.com/evmos/evmos#readme"
22 | }
23 |
--------------------------------------------------------------------------------
/crypto/codec/amino.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package codec
4 |
5 | import (
6 | "github.com/cosmos/cosmos-sdk/codec"
7 | "github.com/cosmos/cosmos-sdk/codec/legacy"
8 | cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
9 | "github.com/cosmos/cosmos-sdk/crypto/keyring"
10 |
11 | "github.com/evmos/os/crypto/ethsecp256k1"
12 | )
13 |
14 | // RegisterCrypto registers all crypto dependency types with the provided Amino
15 | // codec.
16 | func RegisterCrypto(cdc *codec.LegacyAmino) {
17 | cdc.RegisterConcrete(ðsecp256k1.PubKey{},
18 | ethsecp256k1.PubKeyName, nil)
19 | cdc.RegisterConcrete(ðsecp256k1.PrivKey{},
20 | ethsecp256k1.PrivKeyName, nil)
21 |
22 | keyring.RegisterLegacyAminoCodec(cdc)
23 | cryptocodec.RegisterCrypto(cdc)
24 |
25 | // NOTE: update SDK's amino codec to include the ethsecp256k1 keys.
26 | // DO NOT REMOVE unless deprecated on the SDK.
27 | legacy.Cdc = cdc
28 | }
29 |
--------------------------------------------------------------------------------
/crypto/codec/codec.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package codec
4 |
5 | import (
6 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
7 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
8 |
9 | "github.com/evmos/os/crypto/ethsecp256k1"
10 | )
11 |
12 | // RegisterInterfaces register the evmOS key concrete types.
13 | func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
14 | registry.RegisterImplementations((*cryptotypes.PubKey)(nil), ðsecp256k1.PubKey{})
15 | registry.RegisterImplementations((*cryptotypes.PrivKey)(nil), ðsecp256k1.PrivKey{})
16 | }
17 |
--------------------------------------------------------------------------------
/crypto/ethsecp256k1/benchmark_test.go:
--------------------------------------------------------------------------------
1 | package ethsecp256k1
2 |
3 | import (
4 | "fmt"
5 | "testing"
6 | )
7 |
8 | func BenchmarkGenerateKey(b *testing.B) {
9 | b.ReportAllocs()
10 | for i := 0; i < b.N; i++ {
11 | if _, err := GenerateKey(); err != nil {
12 | b.Fatal(err)
13 | }
14 | }
15 | }
16 |
17 | func BenchmarkPubKey_VerifySignature(b *testing.B) {
18 | privKey, err := GenerateKey()
19 | if err != nil {
20 | b.Fatal(err)
21 | }
22 | pubKey := privKey.PubKey()
23 |
24 | b.ResetTimer()
25 | b.ReportAllocs()
26 | for i := 0; i < b.N; i++ {
27 | msg := []byte(fmt.Sprintf("%10d", i))
28 | sig, err := privKey.Sign(msg)
29 | if err != nil {
30 | b.Fatal(err)
31 | }
32 | pubKey.VerifySignature(msg, sig)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/crypto/hd/benchmark_test.go:
--------------------------------------------------------------------------------
1 | package hd
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/cosmos/cosmos-sdk/crypto/keyring"
7 | "github.com/evmos/os/types"
8 | )
9 |
10 | func BenchmarkEthSecp256k1Algo_Derive(b *testing.B) {
11 | b.ReportAllocs()
12 | for i := 0; i < b.N; i++ {
13 | deriveFn := EthSecp256k1.Derive()
14 | if _, err := deriveFn(mnemonic, keyring.DefaultBIP39Passphrase, types.BIP44HDPath); err != nil {
15 | b.Fatal(err)
16 | }
17 | }
18 | }
19 |
20 | func BenchmarkEthSecp256k1Algo_Generate(b *testing.B) {
21 | bz, err := EthSecp256k1.Derive()(mnemonic, keyring.DefaultBIP39Passphrase, types.BIP44HDPath)
22 | if err != nil {
23 | b.Fatal(err)
24 | }
25 |
26 | b.ResetTimer()
27 | b.ReportAllocs()
28 | for i := 0; i < b.N; i++ {
29 | (ðSecp256k1Algo{}).Generate()(bz)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/encoding/codec/codec.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package codec
4 |
5 | import (
6 | "github.com/cosmos/cosmos-sdk/codec"
7 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
8 | "github.com/cosmos/cosmos-sdk/std"
9 | sdk "github.com/cosmos/cosmos-sdk/types"
10 |
11 | cryptocodec "github.com/evmos/os/crypto/codec"
12 | "github.com/evmos/os/types"
13 | )
14 |
15 | // RegisterLegacyAminoCodec registers Interfaces from types, crypto, and SDK std.
16 | func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
17 | sdk.RegisterLegacyAminoCodec(cdc)
18 | cryptocodec.RegisterCrypto(cdc)
19 | codec.RegisterEvidences(cdc)
20 | }
21 |
22 | // RegisterInterfaces registers Interfaces from types, crypto, and SDK std.
23 | func RegisterInterfaces(interfaceRegistry codectypes.InterfaceRegistry) {
24 | std.RegisterInterfaces(interfaceRegistry)
25 | cryptocodec.RegisterInterfaces(interfaceRegistry)
26 | types.RegisterInterfaces(interfaceRegistry)
27 | }
28 |
--------------------------------------------------------------------------------
/encoding/config_test.go:
--------------------------------------------------------------------------------
1 | package encoding_test
2 |
3 | import (
4 | "math/big"
5 | "testing"
6 |
7 | ethtypes "github.com/ethereum/go-ethereum/core/types"
8 | "github.com/evmos/os/encoding"
9 | utiltx "github.com/evmos/os/testutil/tx"
10 | evmtypes "github.com/evmos/os/x/evm/types"
11 | "github.com/stretchr/testify/require"
12 | )
13 |
14 | func TestTxEncoding(t *testing.T) {
15 | addr, key := utiltx.NewAddrKey()
16 | signer := utiltx.NewSigner(key)
17 |
18 | ethTxParams := evmtypes.EvmTxArgs{
19 | ChainID: big.NewInt(1),
20 | Nonce: 1,
21 | Amount: big.NewInt(10),
22 | GasLimit: 100000,
23 | GasFeeCap: big.NewInt(1),
24 | GasTipCap: big.NewInt(1),
25 | Input: []byte{},
26 | }
27 | msg := evmtypes.NewTx(ðTxParams)
28 | msg.From = addr.Hex()
29 |
30 | ethSigner := ethtypes.LatestSignerForChainID(big.NewInt(1))
31 | err := msg.Sign(ethSigner, signer)
32 | require.NoError(t, err)
33 |
34 | cfg := encoding.MakeConfig()
35 |
36 | _, err = cfg.TxConfig.TxEncoder()(msg)
37 | require.Error(t, err, "encoding failed")
38 |
39 | // FIXME: transaction hashing is hardcoded on Tendermint:
40 | // See https://github.com/cometbft/cometbft/issues/6539 for reference
41 | // txHash := msg.AsTransaction().Hash()
42 | // tmTx := cmttypes.Tx(bz)
43 |
44 | // require.Equal(t, txHash.Bytes(), tmTx.Hash())
45 | }
46 |
--------------------------------------------------------------------------------
/ethereum/eip712/domain.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package eip712
4 |
5 | import (
6 | "github.com/ethereum/go-ethereum/common/math"
7 | "github.com/ethereum/go-ethereum/signer/core/apitypes"
8 | )
9 |
10 | // createEIP712Domain creates the typed data domain for the given chainID.
11 | func createEIP712Domain(chainID uint64) apitypes.TypedDataDomain {
12 | domain := apitypes.TypedDataDomain{
13 | Name: "Cosmos Web3",
14 | Version: "1.0.0",
15 | ChainId: math.NewHexOrDecimal256(int64(chainID)), // #nosec G115
16 | VerifyingContract: "cosmos",
17 | Salt: "0",
18 | }
19 |
20 | return domain
21 | }
22 |
--------------------------------------------------------------------------------
/ethereum/eip712/eip712.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package eip712
5 |
6 | import (
7 | "github.com/ethereum/go-ethereum/signer/core/apitypes"
8 | )
9 |
10 | // WrapTxToTypedData wraps an Amino-encoded Cosmos Tx JSON SignDoc
11 | // bytestream into an EIP712-compatible TypedData request.
12 | func WrapTxToTypedData(
13 | chainID uint64,
14 | data []byte,
15 | ) (apitypes.TypedData, error) {
16 | messagePayload, err := createEIP712MessagePayload(data)
17 | message := messagePayload.message
18 | if err != nil {
19 | return apitypes.TypedData{}, err
20 | }
21 |
22 | types, err := createEIP712Types(messagePayload)
23 | if err != nil {
24 | return apitypes.TypedData{}, err
25 | }
26 |
27 | domain := createEIP712Domain(chainID)
28 |
29 | typedData := apitypes.TypedData{
30 | Types: types,
31 | PrimaryType: txField,
32 | Domain: domain,
33 | Message: message,
34 | }
35 |
36 | return typedData, nil
37 | }
38 |
--------------------------------------------------------------------------------
/evmOS_repo_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evmos/os/d14323f1cec649ba36b3382a66b3f5159a531ad1/evmOS_repo_header.png
--------------------------------------------------------------------------------
/example_chain/activators.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package example_chain
4 |
5 | import (
6 | "github.com/evmos/os/example_chain/eips"
7 | "github.com/evmos/os/x/evm/core/vm"
8 | )
9 |
10 | // evmosActivators defines a map of opcode modifiers associated
11 | // with a key defining the corresponding EIP.
12 | var evmosActivators = map[string]func(*vm.JumpTable){
13 | "evmos_0": eips.Enable0000,
14 | "evmos_1": eips.Enable0001,
15 | "evmos_2": eips.Enable0002,
16 | }
17 |
--------------------------------------------------------------------------------
/example_chain/ante/evm_handler.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package ante
5 |
6 | import (
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | evmante "github.com/evmos/os/ante/evm"
9 | )
10 |
11 | // newMonoEVMAnteHandler creates the sdk.AnteHandler implementation for the EVM transactions.
12 | func newMonoEVMAnteHandler(options HandlerOptions) sdk.AnteHandler {
13 | return sdk.ChainAnteDecorators(
14 | evmante.NewEVMMonoDecorator(
15 | options.AccountKeeper,
16 | options.FeeMarketKeeper,
17 | options.EvmKeeper,
18 | options.MaxTxGasWanted,
19 | ),
20 | )
21 | }
22 |
--------------------------------------------------------------------------------
/example_chain/constants.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package example_chain
5 |
6 | const (
7 | // ExampleChainDenom is the denomination of the evmOS example chain's base coin.
8 | ExampleChainDenom = "aevmos"
9 |
10 | // ExampleDisplayDenom is the display denomination of the evmOS example chain's base coin.
11 | ExampleDisplayDenom = "evmos"
12 |
13 | // EighteenDecimalsChainID is the chain ID for the 18 decimals chain.
14 | EighteenDecimalsChainID = "os_9001"
15 |
16 | // SixDecimalsChainID is the chain ID for the 6 decimals chain.
17 | SixDecimalsChainID = "ossix_9002"
18 | )
19 |
--------------------------------------------------------------------------------
/example_chain/eips/eips.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package eips
5 |
6 | import (
7 | "github.com/evmos/os/x/evm/core/vm"
8 | )
9 |
10 | var (
11 | Multiplier = uint64(10)
12 | SstoreConstantGas = uint64(500)
13 | )
14 |
15 | // enable0000 contains the logic to modify the CREATE and CREATE2 opcodes
16 | // constant gas value.
17 | func Enable0000(jt *vm.JumpTable) {
18 | currentValCreate := jt[vm.CREATE].GetConstantGas()
19 | jt[vm.CREATE].SetConstantGas(currentValCreate * Multiplier)
20 |
21 | currentValCreate2 := jt[vm.CREATE2].GetConstantGas()
22 | jt[vm.CREATE2].SetConstantGas(currentValCreate2 * Multiplier)
23 | }
24 |
25 | // enable0001 contains the logic to modify the CALL opcode
26 | // constant gas value.
27 | func Enable0001(jt *vm.JumpTable) {
28 | currentVal := jt[vm.CALL].GetConstantGas()
29 | jt[vm.CALL].SetConstantGas(currentVal * Multiplier)
30 | }
31 |
32 | // enable0002 contains the logic to modify the SSTORE opcode
33 | // constant gas value.
34 | func Enable0002(jt *vm.JumpTable) {
35 | jt[vm.SSTORE].SetConstantGas(SstoreConstantGas)
36 | }
37 |
--------------------------------------------------------------------------------
/example_chain/eips/testdata/Counter.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: LGPL-3.0-only
2 |
3 | pragma solidity >=0.7.0 <0.9.0;
4 |
5 | contract Counter {
6 | uint256 public counter = 1;
7 |
8 | function increment() external {
9 | counter++;
10 | }
11 |
12 | function decrement() external {
13 | counter--;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/example_chain/eips/testdata/CounterFactory.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: LGPL-3.0-only
2 |
3 | pragma solidity >=0.7.0 <0.9.0;
4 |
5 | import "./Counter.sol";
6 |
7 | contract Counterfactory {
8 | Counter public counterInstance;
9 |
10 | constructor() {
11 | counterInstance = new Counter();
12 | }
13 |
14 | function incrementCounter() public {
15 | counterInstance.increment();
16 | }
17 |
18 | function decrementCounter() public {
19 | counterInstance.decrement();
20 | }
21 |
22 | function getCounterValue() public view returns (uint256) {
23 | return counterInstance.counter();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/example_chain/eips/testdata/contracts.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadCounterContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("Counter.json")
13 | }
14 |
15 | func LoadCounterFactoryContract() (evmtypes.CompiledContract, error) {
16 | return contractutils.LoadContractFromJSONFile("CounterFactory.json")
17 | }
18 |
--------------------------------------------------------------------------------
/example_chain/osd/main.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package main
5 |
6 | import (
7 | "fmt"
8 | "os"
9 |
10 | svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
11 | sdk "github.com/cosmos/cosmos-sdk/types"
12 | examplechain "github.com/evmos/os/example_chain"
13 | "github.com/evmos/os/example_chain/osd/cmd"
14 | chainconfig "github.com/evmos/os/example_chain/osd/config"
15 | )
16 |
17 | func main() {
18 | setupSDKConfig()
19 |
20 | rootCmd := cmd.NewRootCmd()
21 | if err := svrcmd.Execute(rootCmd, "osd", examplechain.DefaultNodeHome); err != nil {
22 | fmt.Fprintln(rootCmd.OutOrStderr(), err)
23 | os.Exit(1)
24 | }
25 | }
26 |
27 | func setupSDKConfig() {
28 | config := sdk.GetConfig()
29 | chainconfig.SetBech32Prefixes(config)
30 | config.Seal()
31 | }
32 |
--------------------------------------------------------------------------------
/example_chain/testutil/gas.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testutil
5 |
6 | import (
7 | "cosmossdk.io/math"
8 | )
9 |
10 | var (
11 | // ExampleMinGasPrices defines 20B related to atto units as the minimum gas price value on the fee market module.
12 | // See https://commonwealth.im/evmos/discussion/5073-global-min-gas-price-value-for-cosmos-sdk-and-evm-transaction-choosing-a-value for reference
13 | ExampleMinGasPrices = math.LegacyNewDec(20_000_000_000)
14 |
15 | // ExampleMinGasMultiplier defines the min gas multiplier value on the fee market module.
16 | // 50% of the leftover gas will be refunded
17 | ExampleMinGasMultiplier = math.LegacyNewDecWithPrec(5, 1)
18 | )
19 |
--------------------------------------------------------------------------------
/example_chain/token_pair.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package example_chain
5 |
6 | import erc20types "github.com/evmos/os/x/erc20/types"
7 |
8 | // WEVMOSContractMainnet is the WEVMOS contract address for mainnet
9 | const WEVMOSContractMainnet = "0xD4949664cD82660AaE99bEdc034a0deA8A0bd517"
10 |
11 | // ExampleTokenPairs creates a slice of token pairs, that contains a pair for the native denom of the example chain
12 | // implementation.
13 | var ExampleTokenPairs = []erc20types.TokenPair{
14 | {
15 | Erc20Address: WEVMOSContractMainnet,
16 | Denom: ExampleChainDenom,
17 | Enabled: true,
18 | ContractOwner: erc20types.OWNER_MODULE,
19 | },
20 | }
21 |
--------------------------------------------------------------------------------
/example_chain/upgrades.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package example_chain
5 |
6 | func (app ExampleChain) RegisterUpgradeHandlers() {
7 | // No upgrades registered yet
8 | }
9 |
--------------------------------------------------------------------------------
/ibc/errors.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package ibc
4 |
5 | import "errors"
6 |
7 | var (
8 | ErrNoIBCVoucherDenom = errors.New("denom is not an IBC voucher")
9 | ErrDenomTraceNotFound = errors.New("denom trace not found")
10 | ErrInvalidBaseDenom = errors.New("invalid base denomination")
11 | )
12 |
--------------------------------------------------------------------------------
/mlc_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "retryOn429": true,
3 | "retryCount": 3,
4 | "fallbackRetryDelay": "20s",
5 | "ignorePatterns": [
6 | {
7 | "pattern": "^https://twitter.com/.*"
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/precompiles/bank/testdata/BankCaller.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: LGPL-3.0-only
2 | pragma solidity >=0.8.18;
3 |
4 | import "../IBank.sol";
5 |
6 | contract BankCaller {
7 |
8 | function callBalances(address account) external view returns (Balance[] memory balances) {
9 | return IBANK_CONTRACT.balances(account);
10 | }
11 |
12 | function callTotalSupply() external view returns (Balance[] memory totalSupply) {
13 | return IBANK_CONTRACT.totalSupply();
14 | }
15 |
16 | function callSupplyOf(address erc20Address) external view returns (uint256) {
17 | return IBANK_CONTRACT.supplyOf(erc20Address);
18 | }
19 | }
--------------------------------------------------------------------------------
/precompiles/bank/testdata/bank.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadBankCallerContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("BankCaller.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/bech32/Bech32I.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: LGPL-3.0-only
2 | pragma solidity >=0.8.17;
3 |
4 | /// @dev The Bech32I contract's address.
5 | address constant Bech32_PRECOMPILE_ADDRESS = 0x0000000000000000000000000000000000000400;
6 |
7 | /// @dev The Bech32I contract's instance.
8 | Bech32I constant BECH32_CONTRACT = Bech32I(Bech32_PRECOMPILE_ADDRESS);
9 |
10 | /// @author Evmos Team
11 | /// @title Bech32 Precompiled Contract
12 | /// @dev The interface through which solidity contracts can convert addresses from
13 | /// hex to bech32 and vice versa.
14 | /// @custom:address 0x0000000000000000000000000000000000000400
15 | interface Bech32I {
16 | /// @dev Defines a method for converting a hex formatted address to bech32.
17 | /// @param addr The hex address to be converted.
18 | /// @param prefix The human readable prefix (HRP) of the bech32 address.
19 | /// @return bech32Address The address in bech32 format.
20 | function hexToBech32(
21 | address addr,
22 | string memory prefix
23 | ) external returns (string memory bech32Address);
24 |
25 | /// @dev Defines a method for converting a bech32 formatted address to hex.
26 | /// @param bech32Address The bech32 address to be converted.
27 | /// @return addr The address in hex format.
28 | function bech32ToHex(
29 | string memory bech32Address
30 | ) external returns (address addr);
31 | }
32 |
--------------------------------------------------------------------------------
/precompiles/bech32/abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "_format": "hh-sol-artifact-1",
3 | "contractName": "Bech32I",
4 | "sourceName": "solidity/precompiles/bech32/Bech32I.sol",
5 | "abi": [
6 | {
7 | "inputs": [
8 | {
9 | "internalType": "string",
10 | "name": "bech32Address",
11 | "type": "string"
12 | }
13 | ],
14 | "name": "bech32ToHex",
15 | "outputs": [
16 | {
17 | "internalType": "address",
18 | "name": "addr",
19 | "type": "address"
20 | }
21 | ],
22 | "stateMutability": "nonpayable",
23 | "type": "function"
24 | },
25 | {
26 | "inputs": [
27 | {
28 | "internalType": "address",
29 | "name": "addr",
30 | "type": "address"
31 | },
32 | {
33 | "internalType": "string",
34 | "name": "prefix",
35 | "type": "string"
36 | }
37 | ],
38 | "name": "hexToBech32",
39 | "outputs": [
40 | {
41 | "internalType": "string",
42 | "name": "bech32Address",
43 | "type": "string"
44 | }
45 | ],
46 | "stateMutability": "nonpayable",
47 | "type": "function"
48 | }
49 | ],
50 | "bytecode": "0x",
51 | "deployedBytecode": "0x",
52 | "linkReferences": {},
53 | "deployedLinkReferences": {}
54 | }
55 |
--------------------------------------------------------------------------------
/precompiles/bech32/setup_test.go:
--------------------------------------------------------------------------------
1 | package bech32_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/evmos/os/precompiles/bech32"
7 |
8 | testkeyring "github.com/evmos/os/testutil/integration/os/keyring"
9 | "github.com/evmos/os/testutil/integration/os/network"
10 | "github.com/stretchr/testify/suite"
11 | )
12 |
13 | var s *PrecompileTestSuite
14 |
15 | // PrecompileTestSuite is the implementation of the TestSuite interface for ERC20 precompile
16 | // unit tests.
17 | type PrecompileTestSuite struct {
18 | suite.Suite
19 |
20 | network *network.UnitTestNetwork
21 | keyring testkeyring.Keyring
22 |
23 | precompile *bech32.Precompile
24 | }
25 |
26 | func TestPrecompileTestSuite(t *testing.T) {
27 | s = new(PrecompileTestSuite)
28 | suite.Run(t, s)
29 | }
30 |
31 | func (s *PrecompileTestSuite) SetupTest() {
32 | keyring := testkeyring.New(2)
33 | integrationNetwork := network.NewUnitTestNetwork(
34 | network.WithPreFundedAccounts(keyring.GetAllAccAddrs()...),
35 | )
36 |
37 | s.keyring = keyring
38 | s.network = integrationNetwork
39 |
40 | precompile, err := bech32.NewPrecompile(6000)
41 | s.Require().NoError(err, "failed to create bech32 precompile")
42 |
43 | s.precompile = precompile
44 | }
45 |
--------------------------------------------------------------------------------
/precompiles/common/events.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package common
5 |
6 | import (
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/ethereum/go-ethereum/accounts/abi"
9 | "github.com/ethereum/go-ethereum/common"
10 | "github.com/evmos/os/x/evm/core/vm"
11 | )
12 |
13 | // EmitEventArgs are the arguments required to emit an authorization event.
14 | //
15 | // The event type can be:
16 | // - ApprovalEvent
17 | // - GenericApprovalEvent
18 | // - AllowanceChangeEvent
19 | // - ...
20 | type EmitEventArgs struct {
21 | Ctx sdk.Context
22 | StateDB vm.StateDB
23 | ContractAddr common.Address
24 | ContractEvents map[string]abi.Event
25 | EventData interface{}
26 | }
27 |
--------------------------------------------------------------------------------
/precompiles/common/types_test.go:
--------------------------------------------------------------------------------
1 | package common_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/evmos/os/testutil/constants"
7 |
8 | "cosmossdk.io/math"
9 | sdk "github.com/cosmos/cosmos-sdk/types"
10 | "github.com/evmos/os/precompiles/common"
11 | "github.com/stretchr/testify/require"
12 | )
13 |
14 | var largeAmt, _ = math.NewIntFromString("1000000000000000000000000000000000000000")
15 |
16 | func TestNewCoinsResponse(t *testing.T) {
17 | testCases := []struct {
18 | amount math.Int
19 | }{
20 | {amount: math.NewInt(1)},
21 | {amount: largeAmt},
22 | }
23 |
24 | for _, tc := range testCases {
25 | coin := sdk.NewCoin(constants.ExampleAttoDenom, tc.amount)
26 | coins := sdk.NewCoins(coin)
27 | res := common.NewCoinsResponse(coins)
28 | require.Equal(t, 1, len(res))
29 | require.Equal(t, tc.amount.BigInt(), res[0].Amount)
30 | }
31 | }
32 |
33 | func TestNewDecCoinsResponse(t *testing.T) {
34 | testCases := []struct {
35 | amount math.Int
36 | }{
37 | {amount: math.NewInt(1)},
38 | {amount: largeAmt},
39 | }
40 |
41 | for _, tc := range testCases {
42 | coin := sdk.NewDecCoin(constants.ExampleAttoDenom, tc.amount)
43 | coins := sdk.NewDecCoins(coin)
44 | res := common.NewDecCoinsResponse(coins)
45 | require.Equal(t, 1, len(res))
46 | require.Equal(t, tc.amount.BigInt(), res[0].Amount)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/precompiles/distribution/errors.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package distribution
4 |
5 | const (
6 | // ErrSetWithdrawAddrAuth is raised when no authorization to set the withdraw address exists.
7 | ErrSetWithdrawAddrAuth = "set withdrawer address authorization for address %s does not exist"
8 | // ErrWithdrawDelRewardsAuth is raised when no authorization to withdraw delegation rewards exists.
9 | ErrWithdrawDelRewardsAuth = "withdraw delegation rewards authorization for address %s does not exist"
10 | // ErrWithdrawValCommissionAuth is raised when no authorization to withdraw validator commission exists.
11 | ErrWithdrawValCommissionAuth = "withdraw validator commission authorization for address %s does not exist"
12 | // ErrDifferentValidator is raised when the origin address is not the same as the validator address.
13 | ErrDifferentValidator = "origin address %s is not the same as validator address %s"
14 | )
15 |
--------------------------------------------------------------------------------
/precompiles/erc20/IERC20Metadata.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
3 |
4 | pragma solidity ^0.8.0;
5 |
6 | import "./IERC20.sol";
7 |
8 | /**
9 | * @dev Interface for the optional metadata functions from the ERC20 standard.
10 | *
11 | * _Available since v4.1._
12 | */
13 | interface IERC20Metadata is IERC20 {
14 | /**
15 | * @dev Returns the name of the token.
16 | */
17 | function name() external view returns (string memory);
18 |
19 | /**
20 | * @dev Returns the symbol of the token.
21 | */
22 | function symbol() external view returns (string memory);
23 |
24 | /**
25 | * @dev Returns the decimals places of the token.
26 | */
27 | function decimals() external view returns (uint8);
28 | }
29 |
--------------------------------------------------------------------------------
/precompiles/erc20/errors_test.go:
--------------------------------------------------------------------------------
1 | package erc20_test
2 |
3 | import (
4 | "github.com/evmos/os/precompiles/erc20"
5 | evmtypes "github.com/evmos/os/x/evm/types"
6 | )
7 |
8 | // TODO: This is not yet producing the correct reason bytes so we skip this test for now,
9 | // until that's correctly implemented.
10 | func (s *PrecompileTestSuite) TestBuildExecRevertedError() {
11 | s.T().Skip("skipping until correctly implemented")
12 |
13 | reason := "ERC20: transfer amount exceeds balance"
14 | revErr, err := erc20.BuildExecRevertedErr(reason)
15 | s.Require().NoError(err, "should not error when building revert error")
16 |
17 | revertErr, ok := revErr.(*evmtypes.RevertError)
18 | s.Require().True(ok, "error should be a revert error")
19 |
20 | // Here we expect the correct revert reason that's returned by an ERC20 Solidity contract.
21 | s.Require().Equal(
22 | "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002645524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63650000000000000000000000000000000000000000000000000000",
23 | revertErr.ErrorData(),
24 | "error data should be the revert reason")
25 | }
26 |
--------------------------------------------------------------------------------
/precompiles/erc20/testdata/ERC20Minter_OpenZeppelinV5.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | //
3 | // Based on OpenZeppelin Contracts v5.0.0 (token/ERC20/ERC20.sol)
4 | //
5 | // NOTE: This was compiled using REMIX IDE.
6 |
7 | pragma solidity ^0.8.20;
8 |
9 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.0.0/contracts/token/ERC20/ERC20.sol";
10 |
11 | /**
12 | * @dev {ERC20} token, including:
13 | *
14 | * - ability to mint tokens
15 | *
16 | * ATTENTION: This contract does not restrict minting tokens to any particular address
17 | * and should thus ONLY BE USED FOR TESTING.
18 | */
19 | contract ERC20Minter_OpenZeppelinV5 is ERC20 {
20 | constructor(string memory name, string memory symbol)
21 | ERC20(name, symbol) {}
22 |
23 | function mint(address to, uint256 amount) public {
24 | _mint(to, amount);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/precompiles/erc20/testdata/erc20_allowance_caller.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadERC20AllowanceCaller() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("ERC20AllowanceCaller.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/erc20/testdata/erc20_no_metadata.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadERC20NoMetadataContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("ERC20NoMetadata.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/erc20/testdata/erc20_test_caller.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadERC20TestCaller() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("ERC20TestCaller.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/erc20/testdata/erc20minter_openzeppelinv5.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadERC20MinterV5Contract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LegacyLoadContractFromJSONFile("ERC20Minter_OpenZeppelinV5.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/evidence/errors.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package evidence
5 |
6 | const (
7 | // ErrInvalidEvidenceHash is raised when the evidence hash is invalid.
8 | ErrInvalidEvidenceHash = "invalid request; hash is empty"
9 | // ErrExpectedEquivocation is raised when the evidence is not an Equivocation.
10 | ErrExpectedEquivocation = "invalid evidence type: expected Equivocation"
11 | )
12 |
--------------------------------------------------------------------------------
/precompiles/evidence/tx.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package evidence
5 |
6 | import (
7 | evidencekeeper "cosmossdk.io/x/evidence/keeper"
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | "github.com/ethereum/go-ethereum/accounts/abi"
10 | "github.com/ethereum/go-ethereum/common"
11 | "github.com/evmos/os/x/evm/core/vm"
12 | )
13 |
14 | // SubmitEvidence implements the evidence submission logic for the evidence precompile.
15 | func (p Precompile) SubmitEvidence(
16 | ctx sdk.Context,
17 | origin common.Address,
18 | _ *vm.Contract,
19 | stateDB vm.StateDB,
20 | method *abi.Method,
21 | args []interface{},
22 | ) ([]byte, error) {
23 | msg, err := NewMsgSubmitEvidence(origin, args)
24 | if err != nil {
25 | return nil, err
26 | }
27 |
28 | msgServer := evidencekeeper.NewMsgServerImpl(p.evidenceKeeper)
29 | res, err := msgServer.SubmitEvidence(ctx, msg)
30 | if err != nil {
31 | return nil, err
32 | }
33 |
34 | if err = p.EmitSubmitEvidenceEvent(ctx, stateDB, origin, res.Hash); err != nil {
35 | return nil, err
36 | }
37 |
38 | return method.Outputs.Pack(true)
39 | }
40 |
--------------------------------------------------------------------------------
/precompiles/gov/testdata/GovCaller.sol:
--------------------------------------------------------------------------------
1 | /// SPDX-License-Identifier: LGPL-3.0-only
2 |
3 | pragma solidity >=0.8.18;
4 |
5 | import "../IGov.sol";
6 |
7 | contract GovCaller {
8 | function getParams() external view returns (Params memory params) {
9 | return GOV_CONTRACT.getParams();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/precompiles/gov/testdata/gov.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadGovCallerContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("GovCaller.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/staking/errors.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package staking
4 |
5 | const (
6 | // ErrDecreaseAmountTooBig is raised when the amount by which the allowance should be decreased is greater
7 | // than the authorization limit.
8 | ErrDecreaseAmountTooBig = "amount by which the allowance should be decreased is greater than the authorization limit: %s > %s"
9 | // ErrDifferentOriginFromDelegator is raised when the origin address is not the same as the delegator address.
10 | ErrDifferentOriginFromDelegator = "origin address %s is not the same as delegator address %s"
11 | // ErrNoDelegationFound is raised when no delegation is found for the given delegator and validator addresses.
12 | ErrNoDelegationFound = "delegation with delegator %s not found for validator %s"
13 | // ErrDifferentOriginFromValidator is raised when the origin address is not the same as the validator address.
14 | ErrDifferentOriginFromValidator = "origin address %s is not the same as validator operator address %s"
15 | // ErrCannotCallFromContract is raised when a function cannot be called from a smart contract.
16 | ErrCannotCallFromContract = "this method can only be called directly to the precompile, not from a smart contract"
17 | )
18 |
--------------------------------------------------------------------------------
/precompiles/staking/testdata/staking_caller.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadStakingCallerContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("StakingCaller.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/staking/testdata/staking_caller_two.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadStakingCallerTwoContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("StakingCallerTwo.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/testutil/contracts/Counter.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0
2 |
3 | pragma solidity >=0.7.0 <0.9.0;
4 |
5 | contract Counter {
6 | uint256 counter = 0;
7 | string internal constant ERROR_TOO_LOW = "COUNTER_TOO_LOW";
8 | event Changed(uint256 counter);
9 | event Added(uint256 counter);
10 |
11 | function add() public {
12 | counter++;
13 | emit Added(counter);
14 | emit Changed(counter);
15 | }
16 |
17 | function subtract() public {
18 | require(counter > 0, ERROR_TOO_LOW);
19 | counter--;
20 | emit Changed(counter);
21 | }
22 |
23 | function getCounter() public view returns (uint256) {
24 | return counter;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/precompiles/testutil/contracts/ICounter.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.8.17;
2 |
3 | interface ICounter {
4 | function add() external;
5 | function subtract() external;
6 | function getCounter() external view returns (uint256);
7 | event Changed(uint256 counter);
8 | event Added(uint256 counter);
9 | }
10 |
--------------------------------------------------------------------------------
/precompiles/testutil/contracts/counter.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package contracts
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadCounterContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("Counter.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/testutil/contracts/distribution_caller.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package contracts
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadDistributionCallerContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("DistributionCaller.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/testutil/contracts/flash_loan.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package contracts
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadFlashLoanContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("FlashLoan.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/testutil/contracts/interchain_sender.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package contracts
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadInterchainSenderContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("InterchainSender.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/testutil/contracts/interchain_sender_caller.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package contracts
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadInterchainSenderCallerContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("InterchainSenderCaller.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/testutil/contracts/reverter.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package contracts
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadReverterContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("Reverter.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/testutil/contracts/staking_reverter.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package contracts
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadStakingReverterContract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("StakingReverter.json")
13 | }
14 |
--------------------------------------------------------------------------------
/precompiles/testutil/errors.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testutil
5 |
6 | import (
7 | "fmt"
8 | "strings"
9 |
10 | abci "github.com/cometbft/cometbft/abci/types"
11 | evmtypes "github.com/evmos/os/x/evm/types"
12 | )
13 |
14 | // CheckVMError is a helper function used to check if the transaction is reverted with the expected error message
15 | // in the VmError field of the MsgEthereumResponse struct.
16 | func CheckVMError(res abci.ExecTxResult, expErrMsg string, args ...interface{}) error {
17 | if !res.IsOK() {
18 | return fmt.Errorf("code 0 was expected on response but got code %d", res.Code)
19 | }
20 | ethRes, err := evmtypes.DecodeTxResponse(res.Data)
21 | if err != nil {
22 | return fmt.Errorf("error occurred while decoding the TxResponse. %s", err)
23 | }
24 | expMsg := fmt.Sprintf(expErrMsg, args...)
25 | if !strings.Contains(ethRes.VmError, expMsg) {
26 | return fmt.Errorf("unexpected VmError on response. expected error to contain: %s, received: %s", expMsg, ethRes.VmError)
27 | }
28 | return nil
29 | }
30 |
31 | // CheckEthereumTxFailed checks if there is a VM error in the transaction response and returns the reason.
32 | func CheckEthereumTxFailed(ethRes *evmtypes.MsgEthereumTxResponse) (string, bool) {
33 | reason := ethRes.VmError
34 | return reason, reason != ""
35 | }
36 |
--------------------------------------------------------------------------------
/precompiles/testutil/ibc.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testutil
5 |
6 | import (
7 | transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
8 | )
9 |
10 | var (
11 | UosmoDenomtrace = transfertypes.DenomTrace{
12 | Path: "transfer/channel-0",
13 | BaseDenom: "uosmo",
14 | }
15 | UosmoIbcdenom = UosmoDenomtrace.IBCDenom()
16 |
17 | UatomDenomtrace = transfertypes.DenomTrace{
18 | Path: "transfer/channel-1",
19 | BaseDenom: "uatom",
20 | }
21 | UatomIbcdenom = UatomDenomtrace.IBCDenom()
22 |
23 | UevmosDenomtrace = transfertypes.DenomTrace{
24 | Path: "transfer/channel-0",
25 | BaseDenom: "aevmos",
26 | }
27 | UevmosIbcdenom = UevmosDenomtrace.IBCDenom()
28 |
29 | UatomOsmoDenomtrace = transfertypes.DenomTrace{
30 | Path: "transfer/channel-0/transfer/channel-1",
31 | BaseDenom: "uatom",
32 | }
33 | UatomOsmoIbcdenom = UatomOsmoDenomtrace.IBCDenom()
34 |
35 | AevmosDenomtrace = transfertypes.DenomTrace{
36 | Path: "transfer/channel-0",
37 | BaseDenom: "aevmos",
38 | }
39 | AevmosIbcdenom = AevmosDenomtrace.IBCDenom()
40 | )
41 |
--------------------------------------------------------------------------------
/precompiles/testutil/testing.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testutil
5 |
6 | import (
7 | "math/big"
8 | "testing"
9 |
10 | storetypes "cosmossdk.io/store/types"
11 | sdk "github.com/cosmos/cosmos-sdk/types"
12 | "github.com/ethereum/go-ethereum/common"
13 | "github.com/evmos/os/x/evm/core/vm"
14 | "github.com/stretchr/testify/require"
15 | )
16 |
17 | // NewPrecompileContract creates a new precompile contract and sets the gas meter.
18 | func NewPrecompileContract(t *testing.T, ctx sdk.Context, caller common.Address, precompile vm.ContractRef, gas uint64) (*vm.Contract, sdk.Context) {
19 | contract := vm.NewContract(vm.AccountRef(caller), precompile, big.NewInt(0), gas)
20 | ctx = ctx.WithGasMeter(storetypes.NewInfiniteGasMeter())
21 | initialGas := ctx.GasMeter().GasConsumed()
22 | require.Equal(t, uint64(0), initialGas)
23 | return contract, ctx
24 | }
25 |
--------------------------------------------------------------------------------
/precompiles/werc20/testdata/WEVMOS9TestCaller.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: LGPL-3.0-only
2 | pragma solidity >=0.8.17;
3 |
4 | import "../IWERC20.sol";
5 |
6 | contract WEVMOS9TestCaller {
7 | address payable public immutable WEVMOS;
8 | uint256 public counter;
9 |
10 | constructor(address payable _wrappedTokenAddress) {
11 | WEVMOS = _wrappedTokenAddress;
12 | counter = 0;
13 | }
14 |
15 | event Log(string message);
16 |
17 | function depositWithRevert(bool before, bool aft) public payable {
18 | counter++;
19 |
20 | uint amountIn = msg.value;
21 | IWERC20(WEVMOS).deposit{value: amountIn}();
22 |
23 | if (before) {
24 | require(false, "revert here");
25 | }
26 |
27 | counter--;
28 |
29 | if (aft) {
30 | require(false, "revert here");
31 | }
32 | return;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/precompiles/werc20/testdata/wevmos9.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | // LoadWEVMOS9Contract load the WEVMOS9 contract from the json representation of
12 | // the Solidity contract.
13 | func LoadWEVMOS9Contract() (evmtypes.CompiledContract, error) {
14 | return contractutils.LoadContractFromJSONFile("WEVMOS9.json")
15 | }
16 |
--------------------------------------------------------------------------------
/precompiles/werc20/testdata/wevmos9_test_caller.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadWEVMOS9TestCaller() (evmtypes.CompiledContract, error) {
12 | return contractutils.LoadContractFromJSONFile("WEVMOS9TestCaller.json")
13 | }
14 |
--------------------------------------------------------------------------------
/proto/buf.gen.gogo.yaml:
--------------------------------------------------------------------------------
1 | version: v1
2 | plugins:
3 | - name: gocosmos
4 | out: .
5 | opt: plugins=grpc,Mgoogle/protobuf/any.proto=github.com/cosmos/cosmos-sdk/codec/types
6 | - name: grpc-gateway
7 | out: .
8 | opt: logtostderr=true,allow_colon_final_segments=true
9 |
--------------------------------------------------------------------------------
/proto/buf.gen.pulsar.yaml:
--------------------------------------------------------------------------------
1 | version: v1
2 | managed:
3 | enabled: true
4 | go_package_prefix:
5 | default: cosmossdk.io/api
6 | except:
7 | - buf.build/googleapis/googleapis
8 | - buf.build/cosmos/gogo-proto
9 | - buf.build/cosmos/cosmos-proto
10 | override:
11 | plugins:
12 | - name: go-pulsar
13 | out: ../api
14 | opt: paths=source_relative
15 | - name: go-grpc
16 | out: ../api
17 | opt: paths=source_relative
18 | - name: go-cosmos-orm
19 | out: ../api
20 | opt: paths=source_relative
21 |
--------------------------------------------------------------------------------
/proto/buf.lock:
--------------------------------------------------------------------------------
1 | # Generated by buf. DO NOT EDIT.
2 | version: v1
3 | deps:
4 | - remote: buf.build
5 | owner: cosmos
6 | repository: cosmos-proto
7 | commit: 1935555c206d4afb9e94615dfd0fad31
8 | - remote: buf.build
9 | owner: cosmos
10 | repository: cosmos-sdk
11 | commit: 508e19f5f37549e3a471a2a59b903c00
12 | - remote: buf.build
13 | owner: cosmos
14 | repository: gogo-proto
15 | commit: 34d970b699f84aa382f3c29773a60836
16 | - remote: buf.build
17 | owner: googleapis
18 | repository: googleapis
19 | commit: 783e4b5374fa488ab068d08af9658438
20 |
--------------------------------------------------------------------------------
/proto/buf.yaml:
--------------------------------------------------------------------------------
1 | version: v1
2 | name: buf.build/evmos/os
3 | deps:
4 | - buf.build/cosmos/cosmos-sdk
5 | - buf.build/cosmos/cosmos-proto
6 | - buf.build/cosmos/gogo-proto
7 | - buf.build/googleapis/googleapis
8 | lint:
9 | use:
10 | - DEFAULT
11 | - COMMENTS
12 | - FILE_LOWER_SNAKE_CASE
13 | except:
14 | - UNARY_RPC
15 | - COMMENT_FIELD
16 | - SERVICE_SUFFIX
17 | - PACKAGE_VERSION_SUFFIX
18 | - RPC_REQUEST_STANDARD_NAME
19 | - RPC_REQUEST_RESPONSE_UNIQUE
20 | - RPC_RESPONSE_STANDARD_NAME
21 | - RPC_REQUEST_RESPONSE_UNIQUE
22 | - COMMENT_MESSAGE
23 | - ENUM_ZERO_VALUE_SUFFIX
24 | breaking:
25 | use:
26 | - FILE
27 |
--------------------------------------------------------------------------------
/proto/os/crypto/v1/ethsecp256k1/keys.proto:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | syntax = "proto3";
4 | package os.crypto.v1.ethsecp256k1;
5 |
6 | import "gogoproto/gogo.proto";
7 |
8 | option go_package = "github.com/evmos/os/crypto/ethsecp256k1";
9 |
10 | // PubKey defines a type alias for an ecdsa.PublicKey that implements
11 | // Tendermint's PubKey interface. It represents the 33-byte compressed public
12 | // key format.
13 | message PubKey {
14 | option (gogoproto.goproto_stringer) = false;
15 |
16 | // key is the public key in byte form
17 | bytes key = 1;
18 | }
19 |
20 | // PrivKey defines a type alias for an ecdsa.PrivateKey that implements
21 | // Tendermint's PrivateKey interface.
22 | message PrivKey {
23 | // key is the private key in byte form
24 | bytes key = 1;
25 | }
26 |
--------------------------------------------------------------------------------
/proto/os/feemarket/v1/events.proto:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | syntax = "proto3";
4 | package os.feemarket.v1;
5 |
6 | option go_package = "github.com/evmos/os/x/feemarket/types";
7 |
8 | // EventFeeMarket is the event type for the feemarket module
9 | message EventFeeMarket {
10 | // base_fee for EIP-1559 blocks
11 | string base_fee = 1;
12 | }
13 |
14 | // EventBlockGas defines an Ethereum block gas event
15 | message EventBlockGas {
16 | // height of the block
17 | string height = 1;
18 | // amount of gas wanted by the block
19 | string amount = 2;
20 | }
21 |
--------------------------------------------------------------------------------
/proto/os/feemarket/v1/genesis.proto:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | syntax = "proto3";
4 | package os.feemarket.v1;
5 |
6 | import "amino/amino.proto";
7 | import "gogoproto/gogo.proto";
8 | import "os/feemarket/v1/feemarket.proto";
9 |
10 | option go_package = "github.com/evmos/os/x/feemarket/types";
11 |
12 | // GenesisState defines the feemarket module's genesis state.
13 | message GenesisState {
14 | // params defines all the parameters of the feemarket module.
15 | Params params = 1
16 | [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ];
17 | // DEPRECATED: base fee is the exported value from previous software version.
18 | // Zero by default.
19 | reserved 2;
20 | reserved "base_fee";
21 | // block_gas is the amount of gas wanted on the last block before the upgrade.
22 | // Zero by default.
23 | uint64 block_gas = 3;
24 | }
25 |
--------------------------------------------------------------------------------
/proto/os/types/v1/dynamic_fee.proto:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | syntax = "proto3";
4 | package os.types.v1;
5 |
6 | import "amino/amino.proto";
7 | import "gogoproto/gogo.proto";
8 |
9 | option go_package = "github.com/evmos/os/types";
10 |
11 | // ExtensionOptionDynamicFeeTx is an extension option that specifies the
12 | // maxPrioPrice for cosmos tx
13 | message ExtensionOptionDynamicFeeTx {
14 | // max_priority_price is the same as `max_priority_fee_per_gas` in eip-1559
15 | // spec
16 | string max_priority_price = 1 [
17 | (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
18 | (gogoproto.nullable) = false,
19 | (amino.dont_omitempty) = true
20 | ];
21 | }
22 |
--------------------------------------------------------------------------------
/proto/os/types/v1/indexer.proto:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | syntax = "proto3";
4 | package os.types.v1;
5 |
6 | import "gogoproto/gogo.proto";
7 |
8 | option go_package = "github.com/evmos/os/types";
9 |
10 | // TxResult is the value stored in eth tx indexer
11 | message TxResult {
12 | option (gogoproto.goproto_getters) = false;
13 |
14 | // height of the blockchain
15 | int64 height = 1;
16 | // tx_index of the cosmos transaction
17 | uint32 tx_index = 2;
18 | // msg_index in a batch transaction
19 | uint32 msg_index = 3;
20 |
21 | // eth_tx_index is the index in the list of valid eth tx in the block,
22 | // aka. the transaction list returned by eth_getBlock api.
23 | int32 eth_tx_index = 4;
24 | // failed is true if the eth transaction did not go succeed
25 | bool failed = 5;
26 | // gas_used by the transaction. If it exceeds the block gas limit,
27 | // it's set to gas limit, which is what's actually deducted by ante handler.
28 | uint64 gas_used = 6;
29 | // cumulative_gas_used specifies the cumulated amount of gas used for all
30 | // processed messages within the current batch transaction.
31 | uint64 cumulative_gas_used = 7;
32 | }
33 |
--------------------------------------------------------------------------------
/proto/os/types/v1/web3.proto:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | syntax = "proto3";
4 | package os.types.v1;
5 |
6 | import "gogoproto/gogo.proto";
7 |
8 | option go_package = "github.com/evmos/os/types";
9 |
10 | // ExtensionOptionsWeb3Tx is an extension option that specifies the typed chain
11 | // id, the fee payer as well as its signature data.
12 | message ExtensionOptionsWeb3Tx {
13 | option (gogoproto.goproto_getters) = false;
14 |
15 | // typed_data_chain_id is used only in EIP712 Domain and should match
16 | // Ethereum network ID in a Web3 provider (e.g. Metamask).
17 | uint64 typed_data_chain_id = 1 [
18 | (gogoproto.jsontag) = "typedDataChainID,omitempty",
19 | (gogoproto.customname) = "TypedDataChainID"
20 | ];
21 |
22 | // fee_payer is an account address for the fee payer. It will be validated
23 | // during EIP712 signature checking.
24 | string fee_payer = 2 [ (gogoproto.jsontag) = "feePayer,omitempty" ];
25 |
26 | // fee_payer_sig is a signature data from the fee paying account,
27 | // allows to perform fee delegation when using EIP712 Domain.
28 | bytes fee_payer_sig = 3 [ (gogoproto.jsontag) = "feePayerSig,omitempty" ];
29 | }
30 |
--------------------------------------------------------------------------------
/rpc/backend/feemarket_query_client_test.go:
--------------------------------------------------------------------------------
1 | package backend
2 |
3 | import (
4 | sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
5 | "github.com/evmos/os/rpc/backend/mocks"
6 | rpc "github.com/evmos/os/rpc/types"
7 | feemarkettypes "github.com/evmos/os/x/feemarket/types"
8 | )
9 |
10 | var _ feemarkettypes.QueryClient = &mocks.FeeMarketQueryClient{}
11 |
12 | // Params
13 | func RegisterFeeMarketParams(feeMarketClient *mocks.FeeMarketQueryClient, height int64) {
14 | feeMarketClient.On("Params", rpc.ContextWithHeight(height), &feemarkettypes.QueryParamsRequest{}).
15 | Return(&feemarkettypes.QueryParamsResponse{Params: feemarkettypes.DefaultParams()}, nil)
16 | }
17 |
18 | func RegisterFeeMarketParamsError(feeMarketClient *mocks.FeeMarketQueryClient, height int64) {
19 | feeMarketClient.On("Params", rpc.ContextWithHeight(height), &feemarkettypes.QueryParamsRequest{}).
20 | Return(nil, sdkerrors.ErrInvalidRequest)
21 | }
22 |
--------------------------------------------------------------------------------
/rpc/backend/filters.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package backend
4 |
5 | import (
6 | "github.com/ethereum/go-ethereum/common"
7 | ethtypes "github.com/ethereum/go-ethereum/core/types"
8 | "github.com/pkg/errors"
9 | )
10 |
11 | // GetLogs returns all the logs from all the ethereum transactions in a block.
12 | func (b *Backend) GetLogs(hash common.Hash) ([][]*ethtypes.Log, error) {
13 | resBlock, err := b.TendermintBlockByHash(hash)
14 | if err != nil {
15 | return nil, err
16 | }
17 | if resBlock == nil {
18 | return nil, errors.Errorf("block not found for hash %s", hash)
19 | }
20 | return b.GetLogsByHeight(&resBlock.Block.Header.Height)
21 | }
22 |
23 | // GetLogsByHeight returns all the logs from all the ethereum transactions in a block.
24 | func (b *Backend) GetLogsByHeight(height *int64) ([][]*ethtypes.Log, error) {
25 | // NOTE: we query the state in case the tx result logs are not persisted after an upgrade.
26 | blockRes, err := b.rpcClient.BlockResults(b.ctx, height)
27 | if err != nil {
28 | return nil, err
29 | }
30 |
31 | return GetLogsFromBlockResults(blockRes)
32 | }
33 |
34 | // BloomStatus returns the BloomBitsBlocks and the number of processed sections maintained
35 | // by the chain indexer.
36 | func (b *Backend) BloomStatus() (uint64, uint64) {
37 | return 4096, 0
38 | }
39 |
--------------------------------------------------------------------------------
/rpc/backend/utils_test.go:
--------------------------------------------------------------------------------
1 | package backend
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/cometbft/cometbft/proto/tendermint/crypto"
7 | )
8 |
9 | func mookProofs(num int, withData bool) *crypto.ProofOps {
10 | var proofOps *crypto.ProofOps
11 | if num > 0 {
12 | proofOps = new(crypto.ProofOps)
13 | for i := 0; i < num; i++ {
14 | proof := crypto.ProofOp{}
15 | if withData {
16 | proof.Data = []byte("\n\031\n\003KEY\022\005VALUE\032\013\010\001\030\001 \001*\003\000\002\002")
17 | }
18 | proofOps.Ops = append(proofOps.Ops, proof)
19 | }
20 | }
21 | return proofOps
22 | }
23 |
24 | func (suite *BackendTestSuite) TestGetHexProofs() {
25 | defaultRes := []string{""}
26 | testCases := []struct {
27 | name string
28 | proof *crypto.ProofOps
29 | exp []string
30 | }{
31 | {
32 | "no proof provided",
33 | mookProofs(0, false),
34 | defaultRes,
35 | },
36 | {
37 | "no proof data provided",
38 | mookProofs(1, false),
39 | defaultRes,
40 | },
41 | {
42 | "valid proof provided",
43 | mookProofs(1, true),
44 | []string{"0x0a190a034b4559120556414c55451a0b0801180120012a03000202"},
45 | },
46 | }
47 | for _, tc := range testCases {
48 | suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
49 | suite.Require().Equal(tc.exp, GetHexProofs(tc.proof))
50 | })
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/rpc/namespaces/ethereum/debug/trace_fallback.go:
--------------------------------------------------------------------------------
1 | // Copyright 2016 The go-ethereum Authors
2 | // This file is part of the go-ethereum library.
3 | //
4 | // The go-ethereum library is free software: you can redistribute it and/or modify
5 | // it under the terms of the GNU Lesser General Public License as published by
6 | // the Free Software Foundation, either version 3 of the License, or
7 | // (at your option) any later version.
8 | //
9 | // The go-ethereum library is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | // GNU Lesser General Public License for more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License
15 | // along with the go-ethereum library. If not, see .
16 |
17 | //go:build !go1.5
18 | // +build !go1.5
19 |
20 | // no-op implementation of tracing methods for Go < 1.5.
21 |
22 | package debug
23 |
24 | import (
25 | "errors"
26 | )
27 |
28 | func (*API) StartGoTrace(string file) error {
29 | a.logger.Debug("debug_stopGoTrace", "file", file)
30 | return errors.New("tracing is not supported on Go < 1.5")
31 | }
32 |
33 | func (*API) StopGoTrace() error {
34 | a.logger.Debug("debug_stopGoTrace")
35 | return errors.New("tracing is not supported on Go < 1.5")
36 | }
37 |
--------------------------------------------------------------------------------
/rpc/namespaces/ethereum/miner/api.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package miner
4 |
5 | import (
6 | "github.com/cosmos/cosmos-sdk/server"
7 | "github.com/evmos/os/rpc/backend"
8 |
9 | "github.com/ethereum/go-ethereum/common"
10 | "github.com/ethereum/go-ethereum/common/hexutil"
11 |
12 | "cosmossdk.io/log"
13 | )
14 |
15 | // API is the private miner prefixed set of APIs in the Miner JSON-RPC spec.
16 | type API struct {
17 | ctx *server.Context
18 | logger log.Logger
19 | backend backend.EVMBackend
20 | }
21 |
22 | // NewPrivateAPI creates an instance of the Miner API.
23 | func NewPrivateAPI(
24 | ctx *server.Context,
25 | backend backend.EVMBackend,
26 | ) *API {
27 | return &API{
28 | ctx: ctx,
29 | logger: ctx.Logger.With("api", "miner"),
30 | backend: backend,
31 | }
32 | }
33 |
34 | // SetEtherbase sets the etherbase of the miner
35 | func (api *API) SetEtherbase(etherbase common.Address) bool {
36 | api.logger.Debug("miner_setEtherbase")
37 | return api.backend.SetEtherbase(etherbase)
38 | }
39 |
40 | // SetGasPrice sets the minimum accepted gas price for the miner.
41 | func (api *API) SetGasPrice(gasPrice hexutil.Big) bool {
42 | api.logger.Info(api.ctx.Viper.ConfigFileUsed())
43 | return api.backend.SetGasPrice(gasPrice)
44 | }
45 |
--------------------------------------------------------------------------------
/rpc/namespaces/ethereum/web3/api.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package web3
5 |
6 | import (
7 | "github.com/ethereum/go-ethereum/common/hexutil"
8 | "github.com/ethereum/go-ethereum/crypto"
9 | "github.com/evmos/os/version"
10 | )
11 |
12 | // PublicAPI is the web3_ prefixed set of APIs in the Web3 JSON-RPC spec.
13 | type PublicAPI struct{}
14 |
15 | // NewPublicAPI creates an instance of the Web3 API.
16 | func NewPublicAPI() *PublicAPI {
17 | return &PublicAPI{}
18 | }
19 |
20 | // ClientVersion returns the client version in the Web3 user agent format.
21 | func (a *PublicAPI) ClientVersion() string {
22 | return version.Version()
23 | }
24 |
25 | // Sha3 returns the keccak-256 hash of the passed-in input.
26 | func (a *PublicAPI) Sha3(input string) hexutil.Bytes {
27 | return crypto.Keccak256(hexutil.Bytes(input))
28 | }
29 |
--------------------------------------------------------------------------------
/rpc/types/addrlock.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | import (
6 | "sync"
7 |
8 | "github.com/ethereum/go-ethereum/common"
9 | )
10 |
11 | // AddrLocker is a mutex structure used to avoid querying outdated account data
12 | type AddrLocker struct {
13 | mu sync.Mutex
14 | locks map[common.Address]*sync.Mutex
15 | }
16 |
17 | // lock returns the lock of the given address.
18 | func (l *AddrLocker) lock(address common.Address) *sync.Mutex {
19 | l.mu.Lock()
20 | defer l.mu.Unlock()
21 | if l.locks == nil {
22 | l.locks = make(map[common.Address]*sync.Mutex)
23 | }
24 | if _, ok := l.locks[address]; !ok {
25 | l.locks[address] = new(sync.Mutex)
26 | }
27 | return l.locks[address]
28 | }
29 |
30 | // LockAddr locks an account's mutex. This is used to prevent another tx getting the
31 | // same nonce until the lock is released. The mutex prevents the (an identical nonce) from
32 | // being read again during the time that the first transaction is being signed.
33 | func (l *AddrLocker) LockAddr(address common.Address) {
34 | l.lock(address).Lock()
35 | }
36 |
37 | // UnlockAddr unlocks the mutex of the given account.
38 | func (l *AddrLocker) UnlockAddr(address common.Address) {
39 | l.lock(address).Unlock()
40 | }
41 |
--------------------------------------------------------------------------------
/scripts/compile_smart_contracts/README.md:
--------------------------------------------------------------------------------
1 | # Compiling Smart Contracts
2 |
3 | This tool compiles all smart contracts found in this repository using a Hardhat setup.
4 | The contracts are collected and then copied into the `contracts` directory for compilation.
5 | After compilation, the resulting JSON data is copied back to the source locations.
6 |
7 | **Note**: The tool will compile all smart contracts found
8 | (except for the ignored paths defined in the script)
9 | but only overwrite the compiled JSON data for contracts
10 | that already have a corresponding compiled JSON file in the same directory.
11 | If you want to add a new JSON file to the repository, use the `add` command
12 | described below.
13 |
14 | ## Usage
15 |
16 | To compile the smart contracts, run the following command:
17 |
18 | ```bash
19 | make contracts-compile
20 | ```
21 |
22 | This will compile the smart contracts and generate the JSON files.
23 |
24 | To clean up the generated artifacts, installed dependencies and cached files,
25 | run:
26 |
27 | ```bash
28 | make contracts-clean
29 | ```
30 |
31 | If you want to add a new smart contract and have a JSON file generated for it,
32 | run:
33 |
34 | ```bash
35 | make contracts-add CONTRACT=path/to/contract.sol
36 | ```
37 |
--------------------------------------------------------------------------------
/scripts/compile_smart_contracts/testdata/hardhat.config.js:
--------------------------------------------------------------------------------
1 | /** @type import('hardhat/config').HardhatUserConfig */
2 | module.exports = {
3 | solidity: '0.8.19',
4 | paths: {
5 | sources: './solidity'
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/scripts/compile_smart_contracts/testdata/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "evmos-contracts",
3 | "version": "2.0.0",
4 | "description": "A collection of smart contracts used in the development of the Evmos blockchain.",
5 | "devDependencies": {
6 | "@openzeppelin/contracts": "^4.9.6",
7 | "hardhat": "^2.22.2"
8 | },
9 | "scripts": {
10 | "test": "echo \"Error: no test specified\" && exit 1"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/evmos/evmos.git"
15 | },
16 | "author": "Evmos Core Team",
17 | "license": "ISC",
18 | "bugs": {
19 | "url": "https://github.com/evmos/evmos/issues"
20 | },
21 | "homepage": "https://github.com/evmos/evmos#readme"
22 | }
23 |
--------------------------------------------------------------------------------
/scripts/compile_smart_contracts/testdata/solidity/SimpleContract.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.17;
3 |
4 | contract SimpleContract {
5 | uint256 public value;
6 |
7 | function setValue(uint256 _value) public {
8 | value = _value;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/scripts/generate_protos.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # --------------
4 | # Commands to run locally
5 | # docker run --network host --rm -v $(CURDIR):/workspace --workdir /workspace ghcr.io/cosmos/proto-builder:v0.11.6 sh ./generate_protos.sh
6 | #
7 | set -eo pipefail
8 |
9 | proto_dirs=$(find ./proto -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq)
10 | for dir in $proto_dirs; do
11 | proto_files=$(find "${dir}" -maxdepth 1 -name '*.proto')
12 | for file in $proto_files; do
13 | # Check if the go_package in the file is pointing to evmos
14 | if grep -q "option go_package.*evmos/os" "$file"; then
15 | buf generate --template proto/buf.gen.gogo.yaml "$file"
16 | fi
17 | done
18 | done
19 |
20 | # move proto files to the right places
21 | cp -r github.com/evmos/os/* ./
22 | rm -rf github.com
23 |
--------------------------------------------------------------------------------
/scripts/generate_protos_pulsar.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # this script is for generating protobuf files for the new google.golang.org/protobuf API
4 | set -eo pipefail
5 |
6 | echo "Cleaning API directory"
7 | (
8 | cd api
9 | find ./ -type f \( -iname \*.pulsar.go -o -iname \*.pb.go -o -iname \*.cosmos_orm.go -o -iname \*.pb.gw.go \) -delete
10 | find . -empty -type d -delete
11 | cd ..
12 | )
13 |
14 | echo "Generating API module"
15 | (
16 | cd proto
17 | buf generate --template buf.gen.pulsar.yaml
18 | )
19 |
--------------------------------------------------------------------------------
/scripts/run-solidity-tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | export GOPATH="$HOME"/go
3 | export PATH="$PATH":"$GOPATH"/bin
4 |
5 | # remove existing data
6 | rm -rf "$HOME"/.tmp-osd-solidity-tests
7 |
8 | # used to exit on first error (any non-zero exit code)
9 | set -e
10 |
11 | # build example chain binary
12 | cd example_chain && make install
13 |
14 | cd ../tests/solidity || exit
15 |
16 | if command -v yarn &>/dev/null; then
17 | yarn install
18 | else
19 | curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
20 | echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
21 | sudo apt update && sudo apt install yarn
22 | yarn install
23 | fi
24 |
25 | yarn test --network evmos "$@"
26 |
--------------------------------------------------------------------------------
/shell.nix:
--------------------------------------------------------------------------------
1 | { pkgs ? import {} }:
2 |
3 | pkgs.mkShell {
4 | buildInputs = [
5 | pkgs.nodejs
6 | pkgs.yarn
7 | ];
8 |
9 | shellHook = ''
10 | echo "Node and Yarn are ready for Solidity tests."
11 | '';
12 | }
--------------------------------------------------------------------------------
/tests/integration/ledger/mocks/tendermint.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package mocks
5 |
6 | import (
7 | "context"
8 |
9 | abci "github.com/cometbft/cometbft/abci/types"
10 | tmbytes "github.com/cometbft/cometbft/libs/bytes"
11 | rpcclient "github.com/cometbft/cometbft/rpc/client"
12 | rpcclientmock "github.com/cometbft/cometbft/rpc/client/mock"
13 | coretypes "github.com/cometbft/cometbft/rpc/core/types"
14 | cmttypes "github.com/cometbft/cometbft/types"
15 | )
16 |
17 | type MockCometRPC struct {
18 | rpcclientmock.Client
19 |
20 | responseQuery abci.ResponseQuery
21 | }
22 |
23 | // NewMockCometRPC returns a mock CometRPC implementation.
24 | // It is used for CLI testing.
25 | func NewMockCometRPC(respQuery abci.ResponseQuery) MockCometRPC {
26 | return MockCometRPC{responseQuery: respQuery}
27 | }
28 |
29 | func (MockCometRPC) BroadcastTxSync(context.Context, cmttypes.Tx) (*coretypes.ResultBroadcastTx, error) {
30 | return &coretypes.ResultBroadcastTx{Code: 0}, nil
31 | }
32 |
33 | func (m MockCometRPC) ABCIQueryWithOptions(
34 | _ context.Context,
35 | _ string,
36 | _ tmbytes.HexBytes,
37 | _ rpcclient.ABCIQueryOptions,
38 | ) (*coretypes.ResultABCIQuery, error) {
39 | return &coretypes.ResultABCIQuery{Response: m.responseQuery}, nil
40 | }
41 |
--------------------------------------------------------------------------------
/tests/solidity/.gitattributes:
--------------------------------------------------------------------------------
1 | *.sol linguist-language=Solidity
2 |
--------------------------------------------------------------------------------
/tests/solidity/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | node_modules/
3 | cache/
4 | artifacts/
5 | # don't track the contracts on evmos directory because these are copied from the precompiles pkg of this repo
6 | **/precompiles/contracts/evmos/*
7 |
8 | # ignore package-lock files (only use yarn.lock)
9 | package-lock.json
10 | !yarn.lock
--------------------------------------------------------------------------------
/tests/solidity/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tests-solidity",
3 | "private": true,
4 | "version": "1.0.0",
5 | "author": "Aragon Association ",
6 | "license": "GPL-3.0-or-later",
7 | "workspaces": {
8 | "packages": [
9 | "suites/*"
10 | ],
11 | "nohoist": [
12 | "**/@aragon/contract-helpers-test"
13 | ]
14 | },
15 | "dependencies": {
16 | "truffle": "5.5.8",
17 | "yargs": "^17.0.1",
18 | "patch-package": "^6.4.7"
19 | },
20 | "scripts": {
21 | "test": "node test-helper.js",
22 | "postinstall": "patch-package"
23 | },
24 | "standard": {
25 | "globals": [
26 | "artifacts",
27 | "expect",
28 | "contract",
29 | "beforeEach",
30 | "before",
31 | "web3",
32 | "it",
33 | "assert",
34 | "describe"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/solidity/suites/basic/contracts/Counter.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0
2 |
3 | pragma solidity >=0.7.0 <0.9.0;
4 |
5 | contract Counter {
6 | uint256 counter = 0;
7 | string internal constant ERROR_TOO_LOW = "COUNTER_TOO_LOW";
8 | event Changed(uint256 counter);
9 | event Added(uint256 counter);
10 |
11 | function add() public {
12 | counter++;
13 | emit Added(counter);
14 | emit Changed(counter);
15 | }
16 |
17 | function subtract() public {
18 | require(counter > 0, ERROR_TOO_LOW);
19 | counter--;
20 | emit Changed(counter);
21 | }
22 |
23 | function getCounter() public view returns (uint256) {
24 | return counter;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/solidity/suites/basic/contracts/EventTest.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0
2 |
3 | pragma solidity >=0.7.0 <0.9.0;
4 |
5 | /**
6 | * @title Storage
7 | * @dev Store & retrieve value in a variable
8 | */
9 | contract EventTest {
10 |
11 | uint256 number;
12 |
13 | event ValueStored1(
14 | uint value1
15 | );
16 | event ValueStored2(
17 | string msg,
18 | uint value1
19 | );
20 | event ValueStored3(
21 | string msg,
22 | uint indexed value1,
23 | uint value2
24 | );
25 |
26 | function store(uint256 num) public {
27 | number = num;
28 | }
29 |
30 | function storeWithEvent(uint256 num) public {
31 | number = num;
32 | emit ValueStored1(num);
33 | emit ValueStored2("TestMsg", num);
34 | emit ValueStored3("TestMsg", num, num);
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/tests/solidity/suites/basic/contracts/Storage.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: GPL-3.0
2 |
3 | pragma solidity >=0.7.0 <0.9.0;
4 |
5 | /**
6 | * @title Storage
7 | * @dev Store & retrieve value in a variable
8 | */
9 | contract Storage {
10 |
11 | uint256 number;
12 |
13 | /**
14 | * @dev Store value in variable
15 | * @param num value to store
16 | */
17 | function store(uint256 num) public {
18 | number = num;
19 | }
20 |
21 | /**
22 | * @dev Return value
23 | * @return value of 'number'
24 | */
25 | function retrieve() public view returns (uint256){
26 | return number;
27 | }
28 |
29 | function shouldRevert() pure public {
30 | require(false, 'This must REVERT');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/solidity/suites/basic/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "basic",
3 | "version": "1.0.0",
4 | "author": "Aragon Association ",
5 | "license": "GPL-3.0-or-later",
6 | "scripts": {
7 | "test-ganache": "yarn truffle test",
8 | "test-evmos": "yarn truffle test --network evmos"
9 | },
10 | "devDependencies": {
11 | "truffle-assertions": "^0.9.2"
12 | },
13 | "standard": {
14 | "globals": [
15 | "artifacts",
16 | "expect",
17 | "contract",
18 | "beforeEach",
19 | "before",
20 | "web3",
21 | "it",
22 | "assert",
23 | "describe"
24 | ]
25 | }
26 | }
--------------------------------------------------------------------------------
/tests/solidity/suites/basic/test/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evmos/os/d14323f1cec649ba36b3382a66b3f5159a531ad1/tests/solidity/suites/basic/test/.gitkeep
--------------------------------------------------------------------------------
/tests/solidity/suites/basic/test/events.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef */
2 |
3 | const EventTest = artifacts.require('EventTest')
4 | const truffleAssert = require('truffle-assertions')
5 |
6 | contract('Test EventTest Contract', async function (accounts) {
7 | let eventInstance
8 |
9 | it('should deploy EventTest contract', async function () {
10 | eventInstance = await EventTest.new()
11 | /* eslint-disable no-unused-expressions */
12 | expect(eventInstance.address).not.to.be.undefined
13 | })
14 |
15 | it('should emit events', async function () {
16 | const tx = await eventInstance.storeWithEvent(888)
17 | truffleAssert.eventEmitted(tx, 'ValueStored1', (events) => {
18 | return events['0'].toString() === '888'
19 | })
20 | truffleAssert.eventEmitted(tx, 'ValueStored2', (events) => {
21 | return (
22 | events['0'].toString() === 'TestMsg' && events['1'].toString() === '888'
23 | )
24 | })
25 | truffleAssert.eventEmitted(tx, 'ValueStored3', (events) => {
26 | return (
27 | events['0'].toString() === 'TestMsg' &&
28 | events['1'].toString() === '888' &&
29 | events['2'].toString() === '888'
30 | )
31 | })
32 | })
33 | })
34 |
--------------------------------------------------------------------------------
/tests/solidity/suites/basic/test/revert.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef */
2 |
3 | const Storage = artifacts.require('Storage')
4 |
5 | async function expectRevert (promise) {
6 | try {
7 | await promise
8 | } catch (error) {
9 | if (error.message.indexOf('revert') === -1) {
10 | expect('revert').to.equal(
11 | error.message,
12 | 'Wrong kind of exception received'
13 | )
14 | }
15 | return
16 | }
17 | expect.fail('Expected an exception but none was received')
18 | }
19 |
20 | contract('Test EVM Revert', async function (accounts) {
21 | let storageInstance
22 | it('should deploy Storage contract', async function () {
23 | storageInstance = await Storage.new()
24 | /* eslint-disable no-unused-expressions */
25 | expect(storageInstance.address).not.to.be.undefined
26 | })
27 |
28 | it('should revert when call `shouldRevert()`', async function () {
29 | await expectRevert(storageInstance.shouldRevert())
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/tests/solidity/suites/basic/test/storage.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef */
2 |
3 | const Storage = artifacts.require('Storage')
4 |
5 | contract('Test Storage Contract', async function (accounts) {
6 | let storageInstance
7 |
8 | it('should deploy Storage contract', async function () {
9 | storageInstance = await Storage.new()
10 | /* eslint-disable no-unused-expressions */
11 | expect(storageInstance.address).not.to.be.undefined
12 | })
13 |
14 | it('should successfully store a value', async function () {
15 | const tx = await storageInstance.store(888)
16 | /* eslint-disable no-unused-expressions */
17 | expect(tx.tx).not.to.be.undefined
18 | })
19 |
20 | it('should successfully retrieve a value', async function () {
21 | const value = await storageInstance.retrieve()
22 | expect(value.toString()).to.equal('888')
23 | })
24 | })
25 |
--------------------------------------------------------------------------------
/tests/solidity/suites/basic/truffle-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | networks: {
3 | // Development network is just left as truffle's default settings
4 | evmos: {
5 | host: '127.0.0.1', // Localhost (default: none)
6 | port: 8545, // Standard Ethereum port (default: none)
7 | network_id: '*', // Any network (default: none)
8 | gas: 5000000, // Gas sent with each transaction
9 | gasPrice: 1000000000 // 1 gwei (in wei)
10 | }
11 | },
12 | compilers: {
13 | solc: {
14 | version: '0.8.18'
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/solidity/suites/eip1559/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eip1559",
3 | "version": "1.0.0",
4 | "license": "GPL-3.0-or-later",
5 | "scripts": {
6 | "test-ganache": "yarn truffle test",
7 | "test-evmos": "yarn truffle test --network evmos"
8 | },
9 | "devDependencies": {
10 | "truffle": "^5.4.14",
11 | "truffle-assertions": "^0.9.2"
12 | },
13 | "dependencies": {
14 | "@truffle/hdwallet-provider": "^1.6.0"
15 | },
16 | "standard": {
17 | "globals": [
18 | "artifacts",
19 | "expect",
20 | "contract",
21 | "beforeEach",
22 | "before",
23 | "web3",
24 | "it",
25 | "assert",
26 | "describe"
27 | ]
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/solidity/suites/eip1559/test/eip1559.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef */
2 |
3 | contract('Transaction', async function (accounts) {
4 | it('should send a transaction with EIP-1559 flag', async function () {
5 | const tx = await web3.eth.sendTransaction({
6 | from: accounts[0],
7 | to: accounts[1]
8 | ? accounts[1]
9 | : '0x0000000000000000000000000000000000000000',
10 | value: '10000000',
11 | gas: '21000',
12 | type: '0x2',
13 | common: {
14 | hardfork: 'london'
15 | }
16 | })
17 | assert.equal(tx.type, '0x2', 'Tx type should be 0x2')
18 | })
19 | })
20 |
--------------------------------------------------------------------------------
/tests/solidity/suites/eip1559/truffle-config.js:
--------------------------------------------------------------------------------
1 | // const HDWalletProvider = require('@truffle/hdwallet-provider');
2 |
3 | module.exports = {
4 | networks: {
5 | // Development network is just left as truffle's default settings
6 | evmos: {
7 | host: '127.0.0.1', // Localhost (default: none)
8 | port: 8545, // Standard Ethereum port (default: none)
9 | network_id: '*', // Any network (default: none)
10 | gas: 5000000, // Gas sent with each transaction
11 | gasPrice: 1000000000 // 1 gwei (in wei)
12 | }
13 | },
14 | compilers: {
15 | solc: {
16 | version: '0.8.18'
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/solidity/suites/exception/contracts/TestRevert.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.8.0;
3 |
4 | contract State {
5 | uint256 a = 0;
6 | function set(uint256 input) public {
7 | a = input;
8 | require(a < 10);
9 | }
10 | function force_set(uint256 input) public {
11 | a = input;
12 | }
13 | function query() public view returns(uint256) {
14 | return a;
15 | }
16 | }
17 |
18 | contract TestRevert {
19 | State state;
20 | uint256 b = 0;
21 | uint256 c = 0;
22 | constructor() {
23 | state = new State();
24 | }
25 | function try_set(uint256 input) public {
26 | b = input;
27 | try state.set(input) {
28 | } catch (bytes memory) {
29 | }
30 | c = input;
31 | }
32 | function set(uint256 input) public {
33 | state.force_set(input);
34 | }
35 | function query_a() public view returns(uint256) {
36 | return state.query();
37 | }
38 | function query_b() public view returns(uint256) {
39 | return b;
40 | }
41 | function query_c() public view returns(uint256) {
42 | return c;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests/solidity/suites/exception/contracts/test/Migrations.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.8.0;
3 |
4 | contract Migrations {
5 | address public owner = msg.sender;
6 | uint public last_completed_migration;
7 |
8 | modifier restricted() {
9 | require(
10 | msg.sender == owner,
11 | "This function is restricted to the contract's owner"
12 | );
13 | _;
14 | }
15 |
16 | function setCompleted(uint completed) public restricted {
17 | last_completed_migration = completed;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/solidity/suites/exception/migrations/1_initial_migration.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef */
2 |
3 | const Migrations = artifacts.require('Migrations')
4 |
5 | module.exports = function (deployer) {
6 | deployer.deploy(Migrations)
7 | }
8 |
--------------------------------------------------------------------------------
/tests/solidity/suites/exception/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "exception",
3 | "version": "1.0.0",
4 | "author": "huangyi ",
5 | "license": "GPL-3.0-or-later",
6 | "scripts": {
7 | "test-ganache": "yarn truffle test",
8 | "test-evmos": "yarn truffle test --network evmos"
9 | },
10 | "devDependencies": {
11 | "truffle-assertions": "^0.9.2"
12 | },
13 | "standard": {
14 | "globals": [
15 | "artifacts",
16 | "expect",
17 | "contract",
18 | "beforeEach",
19 | "before",
20 | "web3",
21 | "it",
22 | "assert",
23 | "describe"
24 | ]
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/solidity/suites/exception/test/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evmos/os/d14323f1cec649ba36b3382a66b3f5159a531ad1/tests/solidity/suites/exception/test/.gitkeep
--------------------------------------------------------------------------------
/tests/solidity/suites/exception/test/revert.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef */
2 |
3 | const TestRevert = artifacts.require('TestRevert')
4 |
5 | contract('TestRevert', (accounts) => {
6 | let revert
7 |
8 | beforeEach(async () => {
9 | revert = await TestRevert.new()
10 | })
11 | it('should revert', async () => {
12 | await revert.try_set(10)
13 | let no = await revert.query_a()
14 | assert.equal(no, '0', 'The modification on a should be reverted')
15 | no = await revert.query_b()
16 | assert.equal(no, '10', 'The modification on b should not be reverted')
17 | no = await revert.query_c()
18 | assert.equal(no, '10', 'The modification on c should not be reverted')
19 |
20 | await revert.set(10)
21 | no = await revert.query_a()
22 | assert.equal(no, '10', 'The force set should not be reverted')
23 | })
24 | })
25 |
--------------------------------------------------------------------------------
/tests/solidity/suites/exception/truffle-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | networks: {
3 | // Development network is just left as truffle's default settings
4 | evmos: {
5 | host: '127.0.0.1', // Localhost (default: none)
6 | port: 8545, // Standard Ethereum port (default: none)
7 | network_id: '*', // Any network (default: none)
8 | gas: 5000000, // Gas sent with each transaction
9 | gasPrice: 1000000000 // 1 gwei (in wei)
10 | }
11 | },
12 | compilers: {
13 | solc: {
14 | version: '0.8.18'
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/solidity/suites/opcode/contracts/Migrations.sol:
--------------------------------------------------------------------------------
1 | pragma solidity >=0.4.21 <0.6.0;
2 |
3 | contract Migrations {
4 | address public owner;
5 | uint public last_completed_migration;
6 |
7 | constructor() public {
8 | owner = msg.sender;
9 | }
10 |
11 | modifier restricted() {
12 | if (msg.sender == owner) _;
13 | }
14 |
15 | function setCompleted(uint completed) public restricted {
16 | last_completed_migration = completed;
17 | }
18 |
19 | function upgrade(address new_address) public restricted {
20 | Migrations upgraded = Migrations(new_address);
21 | upgraded.setCompleted(last_completed_migration);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/solidity/suites/opcode/migrations/1_initial_migration.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef */
2 |
3 | const Migrations = artifacts.require('Migrations')
4 |
5 | module.exports = function (deployer) {
6 | deployer.deploy(Migrations)
7 | }
8 |
--------------------------------------------------------------------------------
/tests/solidity/suites/opcode/migrations/2_opCodes_migration.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef */
2 |
3 | const OpCodes = artifacts.require('./OpCodes.sol')
4 |
5 | module.exports = function (deployer) {
6 | deployer.deploy(OpCodes)
7 | }
8 |
--------------------------------------------------------------------------------
/tests/solidity/suites/opcode/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "opcode",
3 | "version": "1.0.0",
4 | "author": "Go Ethereum",
5 | "license": "GPL-3.0-or-later",
6 | "scripts": {
7 | "test-ganache": "yarn truffle test",
8 | "test-evmos": "yarn truffle test --network evmos"
9 | },
10 | "devDependencies": {
11 | "truffle-assertions": "^0.9.2"
12 | },
13 | "standard": {
14 | "globals": [
15 | "artifacts",
16 | "expect",
17 | "contract",
18 | "beforeEach",
19 | "before",
20 | "web3",
21 | "it",
22 | "assert",
23 | "describe"
24 | ]
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/tests/solidity/suites/opcode/test/opCodes.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-undef */
2 | /* eslint-disable no-unused-expressions */
3 |
4 | const TodoList = artifacts.require('./OpCodes.sol')
5 | let contractInstance
6 |
7 | contract('OpCodes', () => {
8 | beforeEach(async () => {
9 | contractInstance = await TodoList.deployed()
10 | })
11 | it('Should run the majority of opcodes without errors', async () => {
12 | let error
13 | try {
14 | await contractInstance.test()
15 | await contractInstance.test_stop()
16 | } catch (err) {
17 | error = err
18 | }
19 | expect(error).to.be.undefined
20 | })
21 |
22 | it('Should throw invalid op code', async () => {
23 | let error
24 | try {
25 | await contractInstance.test_invalid()
26 | } catch (err) {
27 | error = err
28 | }
29 | expect(error).not.to.be.undefined
30 | })
31 |
32 | it('Should revert', async () => {
33 | let error
34 | try {
35 | await contractInstance.test_revert()
36 | } catch (err) {
37 | error = err
38 | }
39 | expect(error).not.to.be.undefined
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/tests/solidity/suites/opcode/truffle-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | networks: {
3 | // Development network is just left as truffle's default settings
4 | evmos: {
5 | host: '127.0.0.1', // Localhost (default: none)
6 | port: 8545, // Standard Ethereum port (default: none)
7 | network_id: '*', // Any network (default: none)
8 | gas: 5000000, // Gas sent with each transaction
9 | gasPrice: 1000000000 // 1 gwei (in wei)
10 | }
11 | },
12 | compilers: {
13 | solc: {
14 | version: '0.5.17'
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/solidity/suites/precompiles/contracts/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/evmos/os/d14323f1cec649ba36b3382a66b3f5159a531ad1/tests/solidity/suites/precompiles/contracts/.gitkeep
--------------------------------------------------------------------------------
/tests/solidity/suites/precompiles/hardhat.config.js:
--------------------------------------------------------------------------------
1 | require("@nomicfoundation/hardhat-toolbox");
2 |
3 | /** @type import('hardhat/config').HardhatUserConfig */
4 | module.exports = {
5 | solidity: {
6 | compilers: [
7 | {
8 | version: "0.8.18",
9 | },
10 | // This version is required to compile the werc9 contract.
11 | {
12 | version: "0.4.22",
13 | },
14 | ],
15 | },
16 | networks: {
17 | evmos: {
18 | url: "http://127.0.0.1:8545",
19 | chainId: 9002,
20 | accounts: [
21 | "0x88CBEAD91AEE890D27BF06E003ADE3D4E952427E88F88D31D61D3EF5E5D54305",
22 | "0x3B7955D25189C99A7468192FCBC6429205C158834053EBE3F78F4512AB432DB9",
23 | ],
24 | },
25 | },
26 | };
27 |
--------------------------------------------------------------------------------
/tests/solidity/suites/precompiles/test/staking.js:
--------------------------------------------------------------------------------
1 | const { expect } = require('chai')
2 | const hre = require('hardhat')
3 |
4 | describe('Staking', function () {
5 | it('should stake EVMOS to a validator', async function () {
6 | const valAddr = 'evmosvaloper10jmp6sgh4cc6zt3e8gw05wavvejgr5pwlawghe'
7 | const stakeAmount = hre.ethers.parseEther('0.001')
8 |
9 | const staking = await hre.ethers.getContractAt(
10 | 'StakingI',
11 | '0x0000000000000000000000000000000000000800'
12 | )
13 |
14 | const [signer] = await hre.ethers.getSigners()
15 | const tx = await staking
16 | .connect(signer)
17 | .delegate(signer, valAddr, stakeAmount)
18 | await tx.wait(1)
19 |
20 | // Query delegation
21 | const delegation = await staking.delegation(signer, valAddr)
22 | expect(delegation.balance.amount).to.equal(
23 | stakeAmount,
24 | 'Stake amount does not match'
25 | )
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/testutil/ante.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testutil
5 |
6 | import sdk "github.com/cosmos/cosmos-sdk/types"
7 |
8 | // NoOpNextFn is a no-op function that returns the context and no error in order to mock
9 | // the next function in the AnteHandler chain.
10 | //
11 | // It can be used in unit tests when calling a decorator's AnteHandle method, e.g.
12 | // `dec.AnteHandle(ctx, tx, false, NoOpNextFn)`
13 | func NoOpNextFn(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.Context, error) {
14 | return ctx, nil
15 | }
16 |
--------------------------------------------------------------------------------
/testutil/constants/constants_test.go:
--------------------------------------------------------------------------------
1 | package constants_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/evmos/os/testutil/constants"
7 |
8 | "github.com/evmos/os/example_chain"
9 | chainconfig "github.com/evmos/os/example_chain/osd/config"
10 | "github.com/stretchr/testify/require"
11 | )
12 |
13 | func TestRequireSameTestDenom(t *testing.T) {
14 | require.Equal(t,
15 | constants.ExampleAttoDenom,
16 | example_chain.ExampleChainDenom,
17 | "test denoms should be the same across the repo",
18 | )
19 | }
20 |
21 | func TestRequireSameTestBech32Prefix(t *testing.T) {
22 | require.Equal(t,
23 | constants.ExampleBech32Prefix,
24 | chainconfig.Bech32Prefix,
25 | "bech32 prefixes should be the same across the repo",
26 | )
27 | }
28 |
29 | func TestRequireSameWEVMOSMainnet(t *testing.T) {
30 | require.Equal(t,
31 | constants.WEVMOSContractMainnet,
32 | example_chain.WEVMOSContractMainnet,
33 | "wevmos contract addresses should be the same across the repo",
34 | )
35 | }
36 |
--------------------------------------------------------------------------------
/testutil/integration/common/factory/factory.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package factory
5 |
6 | import (
7 | "github.com/evmos/os/testutil/integration/os/grpc"
8 | "github.com/evmos/os/testutil/integration/os/network"
9 | )
10 |
11 | const (
12 | GasAdjustment = float64(1.7)
13 | )
14 |
15 | // CoreTxFactory is the interface that wraps the methods
16 | // to build and broadcast cosmos transactions, and also
17 | // includes module-specific transactions
18 | type CoreTxFactory interface {
19 | BaseTxFactory
20 | DistributionTxFactory
21 | StakingTxFactory
22 | FundTxFactory
23 | }
24 |
25 | var _ CoreTxFactory = (*IntegrationTxFactory)(nil)
26 |
27 | // IntegrationTxFactory is a helper struct to build and broadcast transactions
28 | // to the network on integration tests. This is to simulate the behavior of a real user.
29 | type IntegrationTxFactory struct {
30 | BaseTxFactory
31 | DistributionTxFactory
32 | StakingTxFactory
33 | FundTxFactory
34 | }
35 |
36 | // New creates a new IntegrationTxFactory instance
37 | func New(
38 | network network.Network,
39 | grpcHandler grpc.Handler,
40 | ) CoreTxFactory {
41 | bf := newBaseTxFactory(network, grpcHandler)
42 | return &IntegrationTxFactory{
43 | bf,
44 | newDistrTxFactory(bf),
45 | newStakingTxFactory(bf),
46 | newFundTxFactory(bf),
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/testutil/integration/common/factory/types.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package factory
5 |
6 | import (
7 | sdkmath "cosmossdk.io/math"
8 | sdktypes "github.com/cosmos/cosmos-sdk/types"
9 | )
10 |
11 | // CosmosTxArgs contains the params to create a cosmos tx
12 | type CosmosTxArgs struct {
13 | // ChainID is the chain's id in cosmos format, e.g. 'evmos_9000-1'
14 | ChainID string
15 | // Gas to be used on the tx
16 | Gas *uint64
17 | // GasPrice to use on tx
18 | GasPrice *sdkmath.Int
19 | // Fees is the fee to be used on the tx (amount and denom)
20 | Fees sdktypes.Coins
21 | // FeeGranter is the account address of the fee granter
22 | FeeGranter sdktypes.AccAddress
23 | // Msgs slice of messages to include on the tx
24 | Msgs []sdktypes.Msg
25 | }
26 |
--------------------------------------------------------------------------------
/testutil/integration/common/grpc/account.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package grpc
5 |
6 | import (
7 | "context"
8 |
9 | sdk "github.com/cosmos/cosmos-sdk/types"
10 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
11 | )
12 |
13 | // GetAccount returns the account for the given address.
14 | func (gqh *IntegrationHandler) GetAccount(address string) (sdk.AccountI, error) {
15 | authClient := gqh.network.GetAuthClient()
16 | res, err := authClient.Account(context.Background(), &authtypes.QueryAccountRequest{
17 | Address: address,
18 | })
19 | if err != nil {
20 | return nil, err
21 | }
22 |
23 | encodingCgf := gqh.network.GetEncodingConfig()
24 | var acc sdk.AccountI
25 | if err = encodingCgf.InterfaceRegistry.UnpackAny(res.Account, &acc); err != nil {
26 | return nil, err
27 | }
28 | return acc, nil
29 | }
30 |
--------------------------------------------------------------------------------
/testutil/integration/ibc/coordinator/types.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package coordinator
4 |
5 | // Endpoint defines the identifiers for a chain's client, connection, and channel.
6 | type Endpoint struct {
7 | ChainID string
8 | ClientID string
9 | ConnectionID string
10 | ChannelID string
11 | PortID string
12 | }
13 |
14 | // IBCConnection defines the connection between two chains.
15 | type IBCConnection struct {
16 | EndpointA Endpoint
17 | EndpointB Endpoint
18 | }
19 |
--------------------------------------------------------------------------------
/testutil/integration/os/factory/sign.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package factory
4 |
5 | import (
6 | errorsmod "cosmossdk.io/errors"
7 | cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
8 | gethtypes "github.com/ethereum/go-ethereum/core/types"
9 | "github.com/evmos/os/testutil/tx"
10 | evmtypes "github.com/evmos/os/x/evm/types"
11 | )
12 |
13 | // SignMsgEthereumTx signs a MsgEthereumTx with the provided private key and chainID.
14 | func (tf *IntegrationTxFactory) SignMsgEthereumTx(privKey cryptotypes.PrivKey, msgEthereumTx evmtypes.MsgEthereumTx) (evmtypes.MsgEthereumTx, error) {
15 | ethChainID := tf.network.GetEIP155ChainID()
16 | signer := gethtypes.LatestSignerForChainID(ethChainID)
17 | err := msgEthereumTx.Sign(signer, tx.NewSigner(privKey))
18 | if err != nil {
19 | return evmtypes.MsgEthereumTx{}, errorsmod.Wrap(err, "failed to sign transaction")
20 | }
21 | return msgEthereumTx, nil
22 | }
23 |
--------------------------------------------------------------------------------
/testutil/integration/os/grpc/feemarket.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package grpc
4 |
5 | import (
6 | "context"
7 |
8 | feemarkettypes "github.com/evmos/os/x/feemarket/types"
9 | )
10 |
11 | // GetBaseFee returns the base fee from the feemarket module.
12 | func (gqh *IntegrationHandler) GetBaseFee() (*feemarkettypes.QueryBaseFeeResponse, error) {
13 | feeMarketClient := gqh.network.GetFeeMarketClient()
14 | return feeMarketClient.BaseFee(context.Background(), &feemarkettypes.QueryBaseFeeRequest{})
15 | }
16 |
17 | // GetBaseFee returns the base fee from the feemarket module.
18 | func (gqh *IntegrationHandler) GetFeeMarketParams() (*feemarkettypes.QueryParamsResponse, error) {
19 | feeMarketClient := gqh.network.GetFeeMarketClient()
20 | return feeMarketClient.Params(context.Background(), &feemarkettypes.QueryParamsRequest{})
21 | }
22 |
--------------------------------------------------------------------------------
/testutil/integration/os/grpc/gov.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package grpc
5 |
6 | import (
7 | "fmt"
8 | "slices"
9 |
10 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
11 | )
12 |
13 | // GetGovParams returns the gov params from the gov module.
14 | func (gqh *IntegrationHandler) GetGovParams(paramsType string) (*govtypes.QueryParamsResponse, error) {
15 | possibleTypes := []string{"deposit", "tallying", "voting"}
16 | if !slices.Contains(possibleTypes, paramsType) {
17 | return nil, fmt.Errorf("invalid params type: %s\npossible types: %s", paramsType, possibleTypes)
18 | }
19 |
20 | govClient := gqh.network.GetGovClient()
21 | return govClient.Params(gqh.network.GetContext(), &govtypes.QueryParamsRequest{ParamsType: paramsType})
22 | }
23 |
24 | // GetProposal returns the proposal from the gov module.
25 | func (gqh *IntegrationHandler) GetProposal(proposalID uint64) (*govtypes.QueryProposalResponse, error) {
26 | govClient := gqh.network.GetGovClient()
27 | return govClient.Proposal(gqh.network.GetContext(), &govtypes.QueryProposalRequest{ProposalId: proposalID})
28 | }
29 |
--------------------------------------------------------------------------------
/testutil/integration/os/network/example_contracts.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package network
5 |
6 | import (
7 | testconstants "github.com/evmos/os/testutil/constants"
8 | )
9 |
10 | // chainsWEVMOSHex is an utility map used to retrieve the WEVMOS contract
11 | // address in hex format from the chain ID.
12 | //
13 | // TODO: refactor to define this in the example chain initialization and pass as function argument
14 | var chainsWEVMOSHex = map[string]string{
15 | testconstants.ExampleChainID: testconstants.WEVMOSContractMainnet,
16 | }
17 |
18 | // GetWEVMOSContractHex returns the hex format of address for the WEVMOS contract
19 | // given the chainID. If the chainID is not found, it defaults to the mainnet
20 | // address.
21 | func GetWEVMOSContractHex(chainID string) string {
22 | address, found := chainsWEVMOSHex[chainID]
23 |
24 | // default to mainnet address
25 | if !found {
26 | address = chainsWEVMOSHex[testconstants.ExampleChainID]
27 | }
28 |
29 | return address
30 | }
31 |
--------------------------------------------------------------------------------
/testutil/integration/os/network/ibc.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package network
5 |
6 | import (
7 | "testing"
8 |
9 | ibctesting "github.com/cosmos/ibc-go/v8/testing"
10 | )
11 |
12 | // GetIBCChain returns a TestChain instance for the given network.
13 | // Note: the sender accounts are not populated. Do not use this accounts to send transactions during tests.
14 | // The keyring should be used instead.
15 | func (n *IntegrationNetwork) GetIBCChain(t *testing.T, coord *ibctesting.Coordinator) *ibctesting.TestChain {
16 | return &ibctesting.TestChain{
17 | TB: t,
18 | Coordinator: coord,
19 | ChainID: n.GetChainID(),
20 | App: n.app,
21 | CurrentHeader: n.ctx.BlockHeader(),
22 | QueryServer: n.app.GetIBCKeeper(),
23 | TxConfig: n.app.GetTxConfig(),
24 | Codec: n.app.AppCodec(),
25 | Vals: n.valSet,
26 | NextVals: n.valSet,
27 | Signers: n.valSigners,
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/testutil/integration/os/utils/types.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package utils
5 |
6 | import (
7 | "github.com/ethereum/go-ethereum/common"
8 |
9 | sdk "github.com/cosmos/cosmos-sdk/types"
10 | )
11 |
12 | func ValidatorConsAddressToHex(valAddress string) common.Address {
13 | coinbaseAddressBytes := sdk.ConsAddress(valAddress).Bytes()
14 | return common.BytesToAddress(coinbaseAddressBytes)
15 | }
16 |
--------------------------------------------------------------------------------
/testutil/pair.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testutil
5 |
--------------------------------------------------------------------------------
/testutil/statedb.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testutil
5 |
6 | import (
7 | sdk "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/ethereum/go-ethereum/common"
9 | anteinterfaces "github.com/evmos/os/ante/interfaces"
10 | "github.com/evmos/os/x/evm/statedb"
11 | )
12 |
13 | // NewStateDB returns a new StateDB for testing purposes.
14 | func NewStateDB(ctx sdk.Context, evmKeeper anteinterfaces.EVMKeeper) *statedb.StateDB {
15 | return statedb.New(ctx, evmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(ctx.HeaderHash())))
16 | }
17 |
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | [flake8]
2 | max-line-length = 120
3 | exclude = */node_modules
4 | ignore = E203,W503
--------------------------------------------------------------------------------
/types/block.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | import (
6 | math "math"
7 |
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | )
10 |
11 | // BlockGasLimit returns the max gas (limit) defined in the block gas meter. If the meter is not
12 | // set, it returns the max gas from the application consensus params.
13 | // NOTE: see https://github.com/cosmos/cosmos-sdk/issues/9514 for full reference
14 | func BlockGasLimit(ctx sdk.Context) uint64 {
15 | blockGasMeter := ctx.BlockGasMeter()
16 |
17 | // Get the limit from the gas meter only if its not null and not an InfiniteGasMeter
18 | if blockGasMeter != nil && blockGasMeter.Limit() != 0 {
19 | return blockGasMeter.Limit()
20 | }
21 |
22 | // Otherwise get from the consensus parameters
23 | cp := ctx.ConsensusParams()
24 | if cp.Block == nil {
25 | return 0
26 | }
27 |
28 | maxGas := cp.Block.MaxGas
29 |
30 | // Setting max_gas to -1 in Tendermint means there is no limit on the maximum gas consumption for transactions
31 | // https://github.com/cometbft/cometbft/blob/v0.37.2/proto/tendermint/types/params.proto#L25-L27
32 | if maxGas == -1 {
33 | return math.MaxUint64
34 | }
35 |
36 | if maxGas > 0 {
37 | return uint64(maxGas) // #nosec G115 -- maxGas is int64 type. It can never be greater than math.MaxUint64
38 | }
39 |
40 | return 0
41 | }
42 |
--------------------------------------------------------------------------------
/types/codec.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | import (
6 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
7 | sdktypes "github.com/cosmos/cosmos-sdk/types"
8 | "github.com/cosmos/cosmos-sdk/types/tx"
9 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
10 | )
11 |
12 | // RegisterInterfaces registers the tendermint concrete client-related
13 | // implementations and interfaces.
14 | func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
15 | registry.RegisterImplementations(
16 | (*sdktypes.AccountI)(nil),
17 | // TODO: uncomment after moving into migrations for EVM version
18 | // &EthAccount{},
19 | )
20 | registry.RegisterImplementations(
21 | (*authtypes.GenesisAccount)(nil),
22 | // TODO: uncomment after moving into migrations for EVM version
23 | // &EthAccount{},
24 | )
25 | registry.RegisterImplementations(
26 | (*tx.TxExtensionOptionI)(nil),
27 | &ExtensionOptionsWeb3Tx{},
28 | &ExtensionOptionDynamicFeeTx{},
29 | )
30 | }
31 |
--------------------------------------------------------------------------------
/types/dynamic_fee.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | import (
6 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
7 | )
8 |
9 | // HasDynamicFeeExtensionOption returns true if the tx implements the `ExtensionOptionDynamicFeeTx` extension option.
10 | func HasDynamicFeeExtensionOption(anyType *codectypes.Any) bool {
11 | _, ok := anyType.GetCachedValue().(*ExtensionOptionDynamicFeeTx)
12 | return ok
13 | }
14 |
--------------------------------------------------------------------------------
/types/errors.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package types
5 |
6 | import (
7 | errorsmod "cosmossdk.io/errors"
8 | )
9 |
10 | // RootCodespace is the codespace for all errors defined in this package
11 | const RootCodespace = "evmOS"
12 |
13 | // ErrInvalidChainID returns an error resulting from an invalid chain ID.
14 | var ErrInvalidChainID = errorsmod.Register(RootCodespace, 3, "invalid chain ID")
15 |
--------------------------------------------------------------------------------
/types/genesis.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package types
5 |
6 | import "encoding/json"
7 |
8 | // GenesisState of the blockchain is represented here as a map of raw json
9 | // messages key'd by a identifier string.
10 | // The identifier is used to determine which module genesis information belongs
11 | // to so it may be appropriately routed during init chain.
12 | // Within this application default genesis information is retrieved from
13 | // the ModuleBasicManager which populates json from each BasicModule
14 | // object provided to it during init.
15 | type GenesisState map[string]json.RawMessage
16 |
--------------------------------------------------------------------------------
/types/hdpath.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package types
5 |
6 | import (
7 | ethaccounts "github.com/ethereum/go-ethereum/accounts"
8 | )
9 |
10 | var (
11 | // Bip44CoinType satisfies EIP84. See https://github.com/ethereum/EIPs/issues/84 for more info.
12 | Bip44CoinType uint32 = 60
13 |
14 | // BIP44HDPath is the default BIP44 HD path used on Ethereum.
15 | BIP44HDPath = ethaccounts.DefaultBaseDerivationPath.String()
16 | )
17 |
18 | type (
19 | HDPathIterator func() ethaccounts.DerivationPath
20 | )
21 |
22 | // NewHDPathIterator receives a base path as a string and a boolean for the desired iterator type and
23 | // returns a function that iterates over the base HD path, returning the string.
24 | func NewHDPathIterator(basePath string, ledgerIter bool) (HDPathIterator, error) {
25 | hdPath, err := ethaccounts.ParseDerivationPath(basePath)
26 | if err != nil {
27 | return nil, err
28 | }
29 |
30 | if ledgerIter {
31 | return ethaccounts.LedgerLiveIterator(hdPath), nil
32 | }
33 |
34 | return ethaccounts.DefaultIterator(hdPath), nil
35 | }
36 |
--------------------------------------------------------------------------------
/types/indexer.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package types
5 |
6 | import (
7 | abci "github.com/cometbft/cometbft/abci/types"
8 | cmttypes "github.com/cometbft/cometbft/types"
9 | "github.com/ethereum/go-ethereum/common"
10 | )
11 |
12 | // EVMTxIndexer defines the interface of custom eth tx indexer.
13 | type EVMTxIndexer interface {
14 | // LastIndexedBlock returns -1 if indexer db is empty
15 | LastIndexedBlock() (int64, error)
16 | IndexBlock(*cmttypes.Block, []*abci.ExecTxResult) error
17 |
18 | // GetByTxHash returns nil if tx not found.
19 | GetByTxHash(common.Hash) (*TxResult, error)
20 | // GetByBlockAndIndex returns nil if tx not found.
21 | GetByBlockAndIndex(int64, int32) (*TxResult, error)
22 | }
23 |
--------------------------------------------------------------------------------
/types/int.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | import (
6 | fmt "fmt"
7 | math "math"
8 | "math/big"
9 |
10 | errorsmod "cosmossdk.io/errors"
11 | sdkmath "cosmossdk.io/math"
12 | errortypes "github.com/cosmos/cosmos-sdk/types/errors"
13 | )
14 |
15 | const maxBitLen = 256
16 |
17 | // SafeInt64 checks for overflows while casting a uint64 to int64 value.
18 | func SafeInt64(value uint64) (int64, error) {
19 | if value > uint64(math.MaxInt64) {
20 | return 0, errorsmod.Wrapf(errortypes.ErrInvalidHeight, "uint64 value %v cannot exceed %v", value, int64(math.MaxInt64))
21 | }
22 |
23 | return int64(value), nil // #nosec G115 -- checked for int overflow already
24 | }
25 |
26 | // SafeNewIntFromBigInt constructs Int from big.Int, return error if more than 256bits
27 | func SafeNewIntFromBigInt(i *big.Int) (sdkmath.Int, error) {
28 | if !IsValidInt256(i) {
29 | return sdkmath.NewInt(0), fmt.Errorf("big int out of bound: %s", i)
30 | }
31 | return sdkmath.NewIntFromBigInt(i), nil
32 | }
33 |
34 | // IsValidInt256 check the bound of 256 bit number
35 | func IsValidInt256(i *big.Int) bool {
36 | return i == nil || i.BitLen() <= maxBitLen
37 | }
38 |
--------------------------------------------------------------------------------
/types/power.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package types
5 |
6 | import (
7 | "math/big"
8 |
9 | "cosmossdk.io/math"
10 | )
11 |
12 | var (
13 | // AttoPowerReduction defines the power reduction for att units (1e18)
14 | AttoPowerReduction = math.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))
15 |
16 | // MicroPowerReduction defines the power reduction for micro units (1e6)
17 | MicroPowerReduction = math.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(6), nil))
18 | )
19 |
--------------------------------------------------------------------------------
/types/protocol.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | // Constants to match up protocol versions and messages
6 | const (
7 | eth65 = 65
8 |
9 | // ProtocolVersion is the latest supported version of the eth protocol.
10 | ProtocolVersion = eth65
11 | )
12 |
--------------------------------------------------------------------------------
/utils/eth/eth.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package eth
5 |
6 | import "math/big"
7 |
8 | // DeriveChainID derives the chain id from the given v parameter.
9 | //
10 | // CONTRACT: v value is either:
11 | //
12 | // - {0,1} + CHAIN_ID * 2 + 35, if EIP155 is used
13 | // - {0,1} + 27, otherwise
14 | //
15 | // Ref: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
16 | func DeriveChainID(v *big.Int) *big.Int {
17 | if v == nil || v.Sign() < 1 {
18 | return nil
19 | }
20 |
21 | if v.BitLen() <= 64 {
22 | v := v.Uint64()
23 | if v == 27 || v == 28 {
24 | return new(big.Int)
25 | }
26 |
27 | if v < 35 {
28 | return nil
29 | }
30 |
31 | // V MUST be of the form {0,1} + CHAIN_ID * 2 + 35
32 | return new(big.Int).SetUint64((v - 35) / 2)
33 | }
34 | v = new(big.Int).Sub(v, big.NewInt(35))
35 | return v.Div(v, big.NewInt(2))
36 | }
37 |
38 | // RawSignatureValues is a helper function
39 | // that parses the v,r and s fields of an Ethereum transaction
40 | func RawSignatureValues(vBz, rBz, sBz []byte) (v, r, s *big.Int) {
41 | if len(vBz) > 0 {
42 | v = new(big.Int).SetBytes(vBz)
43 | }
44 | if len(rBz) > 0 {
45 | r = new(big.Int).SetBytes(rBz)
46 | }
47 | if len(sBz) > 0 {
48 | s = new(big.Int).SetBytes(sBz)
49 | }
50 | return v, r, s
51 | }
52 |
--------------------------------------------------------------------------------
/version/version.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package version
5 |
6 | import (
7 | "fmt"
8 | "runtime"
9 | )
10 |
11 | var (
12 | AppVersion = ""
13 | GitCommit = ""
14 | BuildDate = ""
15 |
16 | GoVersion = ""
17 | GoArch = ""
18 | )
19 |
20 | func init() {
21 | if len(AppVersion) == 0 {
22 | AppVersion = "dev"
23 | }
24 |
25 | GoVersion = runtime.Version()
26 | GoArch = runtime.GOARCH
27 | }
28 |
29 | func Version() string {
30 | return fmt.Sprintf(
31 | "Version %s (%s)\nCompiled at %s using Go %s (%s)",
32 | AppVersion,
33 | GitCommit,
34 | BuildDate,
35 | GoVersion,
36 | GoArch,
37 | )
38 | }
39 |
--------------------------------------------------------------------------------
/x/erc20/client/cli/metadata/coin_metadata_test.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": [
3 | {
4 | "description": "The native staking and governance token of the Evmos chain",
5 | "denom_units": [
6 | {
7 | "denom": "aevmos",
8 | "exponent": 0
9 | },
10 | {
11 | "denom": "evmos",
12 | "exponent": 18
13 | }
14 | ],
15 | "base": "aevmos",
16 | "display": "aevmos",
17 | "name": "aevmos",
18 | "symbol": "EVMOS"
19 | }
20 | ]
21 | }
--------------------------------------------------------------------------------
/x/erc20/client/cli/metadata/coins_metadata_test.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": [
3 | {
4 | "description": "The native staking and governance token of the Evmos chain",
5 | "denom_units": [
6 | {
7 | "denom": "aevmos",
8 | "exponent": 0
9 | },
10 | {
11 | "denom": "evmos",
12 | "exponent": 18
13 | }
14 | ],
15 | "base": "aevmos",
16 | "display": "aevmos",
17 | "name": "aevmos",
18 | "symbol": "EVMOS"
19 | },
20 | {
21 | "description": "The native staking and governance token of the Osmosis chain",
22 | "denom_units": [
23 | {
24 | "denom": "ibc/0429A217F7AFD21E67CABA80049DD56BB0380B77E9C58C831366D6626D42F399",
25 | "exponent": 0,
26 | "aliases": [
27 | "ibcuosmo"
28 | ]
29 | },
30 | {
31 | "denom": "OSMO",
32 | "exponent": 6
33 | }
34 | ],
35 | "base": "ibc/0429A217F7AFD21E67CABA80049DD56BB0380B77E9C58C831366D6626D42F399",
36 | "display": "OSMO",
37 | "name": "Osmo",
38 | "symbol": "OSMO"
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/x/erc20/client/cli/metadata/invalid_metadata_test.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": [
3 | {
4 | "description": 1,
5 | "denom_units": [
6 | {
7 | "denom": "aevmos",
8 | "exponent": 0
9 | },
10 | {
11 | "denom": "evmos",
12 | "exponent": 18
13 | }
14 | ],
15 | "base": "aevmos",
16 | "display": "aevmos",
17 | "name": "aevmos",
18 | "symbol": "EVMOS"
19 | }
20 | ]
21 | }
--------------------------------------------------------------------------------
/x/erc20/genesis.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package erc20
5 |
6 | import (
7 | "fmt"
8 |
9 | sdk "github.com/cosmos/cosmos-sdk/types"
10 | authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
11 | "github.com/evmos/os/x/erc20/keeper"
12 | "github.com/evmos/os/x/erc20/types"
13 | )
14 |
15 | // InitGenesis import module genesis
16 | func InitGenesis(
17 | ctx sdk.Context,
18 | k keeper.Keeper,
19 | accountKeeper authkeeper.AccountKeeper,
20 | data types.GenesisState,
21 | ) {
22 | err := k.SetParams(ctx, data.Params)
23 | if err != nil {
24 | panic(fmt.Errorf("error setting params %s", err))
25 | }
26 |
27 | // ensure erc20 module account is set on genesis
28 | if acc := accountKeeper.GetModuleAccount(ctx, types.ModuleName); acc == nil {
29 | // NOTE: shouldn't occur
30 | panic("the erc20 module account has not been set")
31 | }
32 |
33 | for _, pair := range data.TokenPairs {
34 | k.SetToken(ctx, pair)
35 | }
36 | }
37 |
38 | // ExportGenesis export module status
39 | func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState {
40 | return &types.GenesisState{
41 | Params: k.GetParams(ctx),
42 | TokenPairs: k.GetTokenPairs(ctx),
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/x/erc20/keeper/testdata/ERC20DirectBalanceManipulation.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 |
3 | pragma solidity ^0.8.0;
4 |
5 | import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol";
6 |
7 | // This is an evil token. Whenever an A -> B transfer is called, half of the amount goes to B
8 | // and half to a predefined C
9 | contract ERC20DirectBalanceManipulation is ERC20PresetMinterPauser {
10 | address private _thief = 0x4dC6ac40Af078661fc43823086E1513635Eeab14;
11 | constructor(uint256 initialSupply)
12 | ERC20PresetMinterPauser("ERC20DirectBalanceManipulation", "ERC20DirectBalanceManipulation") {
13 | _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
14 | _mint(msg.sender, initialSupply);
15 | }
16 | function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
17 | // Any time a transaction happens, the thief account siphons half.
18 | uint256 half = amount / 2;
19 |
20 | super.transfer(_thief, amount - half); // a - h for rounding
21 | return super.transfer(recipient, half);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/x/erc20/keeper/testdata/ERC20MaliciousDelayed.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 |
3 | pragma solidity ^0.8.0;
4 |
5 | import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol";
6 |
7 | // This is an evil token. Whenever an A -> B transfer is called,
8 | // a predefined C is given a massive allowance on B.
9 | contract ERC20MaliciousDelayed is ERC20PresetMinterPauser {
10 | address private _thief = 0x4dC6ac40Af078661fc43823086E1513635Eeab14;
11 | uint256 private _bigNum = 1000000000000000000; // ~uint256(0)
12 | constructor(uint256 initialSupply)
13 | ERC20PresetMinterPauser("ERC20MaliciousDelayed", "ERC20MALICIOUSDELAYED") {
14 | _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
15 | _mint(msg.sender, initialSupply);
16 |
17 | }
18 | function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
19 | // Any time a transaction happens, the thief account is granted allowance in secret.
20 | // Still emits an Approve!
21 | super._approve(recipient, _thief, _bigNum);
22 | return super.transfer(recipient, amount);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/x/erc20/keeper/testdata/erc20DirectBalanceManipulation.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | // LoadBalanceManipulationContract loads the ERC20DirectBalanceManipulation contract
12 | // from the compiled JSON data.
13 | //
14 | // This is an evil token. Whenever an A -> B transfer is called,
15 | // a predefined C is given a massive allowance on B.
16 | func LoadBalanceManipulationContract() (evmtypes.CompiledContract, error) {
17 | return contractutils.LoadContractFromJSONFile("ERC20DirectBalanceManipulation.json")
18 | }
19 |
--------------------------------------------------------------------------------
/x/erc20/keeper/testdata/erc20maliciousdelayed.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | // LoadMaliciousDelayedContract loads the ERC20MaliciousDelayed contract.
12 | //
13 | // This is an evil token. Whenever an A -> B transfer is called,
14 | // a predefined C is given a massive allowance on B.
15 | func LoadMaliciousDelayedContract() (evmtypes.CompiledContract, error) {
16 | return contractutils.LoadContractFromJSONFile("ERC20MaliciousDelayed.json")
17 | }
18 |
--------------------------------------------------------------------------------
/x/erc20/types/events.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package types
5 |
6 | import (
7 | "math/big"
8 |
9 | "github.com/ethereum/go-ethereum/common"
10 | )
11 |
12 | // erc20 events
13 | const (
14 | EventTypeConvertERC20 = "convert_erc20"
15 | EventTypeRegisterERC20 = "register_erc20"
16 | EventTypeToggleTokenConversion = "toggle_token_conversion" // #nosec
17 | EventTypeRegisterERC20Extension = "register_erc20_extension"
18 |
19 | AttributeCoinSourceChannel = "source_channel"
20 | AttributeKeyCosmosCoin = "cosmos_coin"
21 | AttributeKeyERC20Token = "erc20_token" // #nosec
22 | AttributeKeyReceiver = "receiver"
23 | )
24 |
25 | // LogTransfer Event type for Transfer(address from, address to, uint256 value)
26 | type LogTransfer struct {
27 | From common.Address
28 | To common.Address
29 | Tokens *big.Int
30 | }
31 |
--------------------------------------------------------------------------------
/x/erc20/types/evm.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package types
5 |
6 | // ERC20Data represents the ERC20 token details used to map
7 | // the token to a Cosmos Coin
8 | type ERC20Data struct {
9 | Name string
10 | Symbol string
11 | Decimals uint8
12 | }
13 |
14 | // ERC20StringResponse defines the string value from the call response
15 | type ERC20StringResponse struct {
16 | Value string
17 | }
18 |
19 | // ERC20Uint8Response defines the uint8 value from the call response
20 | type ERC20Uint8Response struct {
21 | Value uint8
22 | }
23 |
24 | // ERC20BoolResponse defines the bool value from the call response
25 | type ERC20BoolResponse struct {
26 | Value bool
27 | }
28 |
29 | // NewERC20Data creates a new ERC20Data instance
30 | func NewERC20Data(name, symbol string, decimals uint8) ERC20Data {
31 | return ERC20Data{
32 | Name: name,
33 | Symbol: symbol,
34 | Decimals: decimals,
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/x/erc20/types/evm_test.go:
--------------------------------------------------------------------------------
1 | package types_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/evmos/os/x/erc20/types"
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestNewERC20Data(t *testing.T) {
11 | data := types.NewERC20Data("test", "ERC20", uint8(18))
12 | exp := types.ERC20Data{Name: "test", Symbol: "ERC20", Decimals: 0x12}
13 | require.Equal(t, exp, data)
14 | }
15 |
--------------------------------------------------------------------------------
/x/erc20/types/keys.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package types
5 |
6 | import (
7 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
8 | "github.com/ethereum/go-ethereum/common"
9 | )
10 |
11 | // constants
12 | const (
13 | // module name
14 | ModuleName = "erc20"
15 |
16 | // StoreKey to be used when creating the KVStore
17 | StoreKey = ModuleName
18 |
19 | // RouterKey to be used for message routing
20 | RouterKey = ModuleName
21 | )
22 |
23 | // ModuleAddress is the native module address for ERC-20
24 | var ModuleAddress common.Address
25 |
26 | func init() {
27 | ModuleAddress = common.BytesToAddress(authtypes.NewModuleAddress(ModuleName).Bytes())
28 | }
29 |
30 | // prefix bytes for the ERC-20 persistent store
31 | const (
32 | prefixTokenPair = iota + 1
33 | prefixTokenPairByERC20
34 | prefixTokenPairByDenom
35 | prefixSTRv2Addresses
36 | )
37 |
38 | // KVStore key prefixes
39 | var (
40 | KeyPrefixTokenPair = []byte{prefixTokenPair}
41 | KeyPrefixTokenPairByERC20 = []byte{prefixTokenPairByERC20}
42 | KeyPrefixTokenPairByDenom = []byte{prefixTokenPairByDenom}
43 | KeyPrefixSTRv2Addresses = []byte{prefixSTRv2Addresses}
44 | )
45 |
--------------------------------------------------------------------------------
/x/erc20/types/mocks/README.md:
--------------------------------------------------------------------------------
1 | # Mocks
2 |
3 | The mocks in this folder have been generated using the [mockery](https://vektra.github.io/mockery/latest/) tool.
4 | To regenerate the mocks, run the following commands at the root of this repository:
5 |
6 | - `BankKeeper` (from used version of Cosmos SDK):
7 |
8 | ```bash
9 | # update the currently used version
10 | COSMOS_VERSION="v0.50.9-evmos"
11 | CUR_DIR="$(pwd)"
12 | TMP_DIR="/tmp/tmp-sdk-mocks-$(date +%s)"
13 |
14 | echo "Cloning Cosmos SDK $COSMOS_VERSION into $TMP_DIR..." &&
15 | git clone --depth 1 --branch "$COSMOS_VERSION" https://github.com/evmos/cosmos-sdk.git "$TMP_DIR" &&
16 | cd "$TMP_DIR" &&
17 |
18 | # Go into bank module and generate mock
19 | echo "Generating mocks for bank keeper..." &&
20 | cd x/bank/keeper &&
21 | mockery --name Keeper &&
22 | sed -i '' 's/\([^a-zA-Z]\)Keeper/\1BankKeeper/g' mocks/Keeper.go &&
23 | mv mocks/Keeper.go "$CUR_DIR/x/erc20/types/mocks/BankKeeper.go" &&
24 |
25 | # Clean up
26 | echo "Cleaning up $TMP_DIR..." &&
27 | cd "$CUR_DIR" &&
28 | rm -rf "$TMP_DIR"
29 |
30 | echo "Done."
31 | ```
32 |
33 | - `EVMKeeper` (reduced interface defined in ERC20 types):
34 |
35 | ```bash
36 | cd x/erc20/types
37 | mockery --name EVMKeeper
38 | ```
39 |
--------------------------------------------------------------------------------
/x/evm/ante/ctx.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package ante
5 |
6 | import (
7 | storetypes "cosmossdk.io/store/types"
8 | sdktypes "github.com/cosmos/cosmos-sdk/types"
9 | )
10 |
11 | // BuildEvmExecutionCtx builds the context needed prior to executing an EVM transaction.
12 | // It does the following:
13 | // 1. Sets an empty KV gas config for gas to be calculated by opcodes
14 | // and not kvstore actions
15 | // 2. Setup an empty transient KV gas config for transient gas to be
16 | // calculated by opcodes
17 | func BuildEvmExecutionCtx(ctx sdktypes.Context) sdktypes.Context {
18 | // We need to setup an empty gas config so that the gas is consistent with Ethereum.
19 | return ctx.WithKVGasConfig(storetypes.GasConfig{}).
20 | WithTransientKVGasConfig(storetypes.GasConfig{})
21 | }
22 |
--------------------------------------------------------------------------------
/x/evm/ante/ctx_test.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package ante_test
5 |
6 | import (
7 | storetypes "cosmossdk.io/store/types"
8 | "github.com/evmos/os/testutil/integration/os/network"
9 | evmante "github.com/evmos/os/x/evm/ante"
10 | )
11 |
12 | func (suite *EvmAnteTestSuite) TestBuildEvmExecutionCtx() {
13 | network := network.New()
14 |
15 | ctx := evmante.BuildEvmExecutionCtx(network.GetContext())
16 |
17 | suite.Equal(storetypes.GasConfig{}, ctx.KVGasConfig())
18 | suite.Equal(storetypes.GasConfig{}, ctx.TransientKVGasConfig())
19 | }
20 |
--------------------------------------------------------------------------------
/x/evm/ante/suite_test.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package ante_test
5 |
6 | import (
7 | "testing"
8 |
9 | "github.com/stretchr/testify/suite"
10 | )
11 |
12 | type EvmAnteTestSuite struct {
13 | suite.Suite
14 | }
15 |
16 | func TestEvmAnteTestSuite(t *testing.T) {
17 | suite.Run(t, &EvmAnteTestSuite{})
18 | }
19 |
--------------------------------------------------------------------------------
/x/evm/client/cli/utils.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package cli
5 |
6 | import (
7 | "fmt"
8 | "strings"
9 |
10 | sdk "github.com/cosmos/cosmos-sdk/types"
11 | "github.com/ethereum/go-ethereum/common"
12 | "github.com/pkg/errors"
13 | )
14 |
15 | func accountToHex(addr string) (string, error) {
16 | if strings.HasPrefix(addr, sdk.GetConfig().GetBech32AccountAddrPrefix()) {
17 | // Check to see if address is Cosmos bech32 formatted
18 | toAddr, err := sdk.AccAddressFromBech32(addr)
19 | if err != nil {
20 | return "", errors.Wrap(err, "must provide a valid Bech32 address")
21 | }
22 | ethAddr := common.BytesToAddress(toAddr.Bytes())
23 | return ethAddr.Hex(), nil
24 | }
25 |
26 | if !strings.HasPrefix(addr, "0x") {
27 | addr = "0x" + addr
28 | }
29 |
30 | valid := common.IsHexAddress(addr)
31 | if !valid {
32 | return "", fmt.Errorf("%s is not a valid Ethereum or Cosmos address", addr)
33 | }
34 |
35 | ethAddr := common.HexToAddress(addr)
36 |
37 | return ethAddr.Hex(), nil
38 | }
39 |
40 | func formatKeyToHash(key string) string {
41 | if !strings.HasPrefix(key, "0x") {
42 | key = "0x" + key
43 | }
44 |
45 | ethkey := common.HexToHash(key)
46 |
47 | return ethkey.Hex()
48 | }
49 |
--------------------------------------------------------------------------------
/x/evm/core/core/utils.go:
--------------------------------------------------------------------------------
1 | package core
2 |
3 | import (
4 | "math/big"
5 |
6 | "github.com/ethereum/go-ethereum/common"
7 | "github.com/ethereum/go-ethereum/core/types"
8 | "github.com/evmos/os/x/evm/core/vm"
9 | )
10 |
11 | // CanTransfer checks whether there are enough funds in the address' account to make a transfer.
12 | // This does not take the necessary gas in to account to make the transfer valid.
13 | func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool {
14 | return db.GetBalance(addr).Cmp(amount) >= 0
15 | }
16 |
17 | // Transfer subtracts amount from sender and adds amount to recipient using the given Db
18 | func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int) {
19 | db.SubBalance(sender, amount)
20 | db.AddBalance(recipient, amount)
21 | }
22 |
23 | // Message represents a message sent to a contract.
24 | type Message interface {
25 | From() common.Address
26 | To() *common.Address
27 |
28 | GasPrice() *big.Int
29 | GasFeeCap() *big.Int
30 | GasTipCap() *big.Int
31 | Gas() uint64
32 | Value() *big.Int
33 |
34 | Nonce() uint64
35 | IsFake() bool
36 | Data() []byte
37 | AccessList() types.AccessList
38 | }
39 |
40 | // NewEVMTxContext creates a new transaction context for a single transaction.
41 | func NewEVMTxContext(msg Message) vm.TxContext {
42 | return vm.TxContext{
43 | Origin: msg.From(),
44 | GasPrice: new(big.Int).Set(msg.GasPrice()),
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/x/evm/core/tracers/js/internal/tracers/noop_tracer_legacy.js:
--------------------------------------------------------------------------------
1 | // Copyright 2017 The go-ethereum Authors
2 | // This file is part of the go-ethereum library.
3 | //
4 | // The go-ethereum library is free software: you can redistribute it and/or modify
5 | // it under the terms of the GNU Lesser General Public License as published by
6 | // the Free Software Foundation, either version 3 of the License, or
7 | // (at your option) any later version.
8 | //
9 | // The go-ethereum library is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | // GNU Lesser General Public License for more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License
15 | // along with the go-ethereum library. If not, see .
16 |
17 | // noopTracer is just the barebone boilerplate code required from a JavaScript
18 | // object to be usable as a transaction tracer.
19 | {
20 | // step is invoked for every opcode that the VM executes.
21 | step: function(log, db) { },
22 |
23 | // fault is invoked when the actual execution of an opcode fails.
24 | fault: function(log, db) { },
25 |
26 | // result is invoked when all the opcodes have been iterated over and returns
27 | // the final result of the tracing.
28 | result: function(ctx, db) { return {}; }
29 | }
30 |
--------------------------------------------------------------------------------
/x/evm/core/vm/custom_eip_testing.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | //go:build test
5 | // +build test
6 |
7 | // This file is used to allow the testing of EVM configuration initialization
8 | // without the need to introduce testing requirements in the final binary. In
9 | // this case, the file provides the possibility to restore the EIP activator
10 | // functions to the initial state without the need to compile ResetActivators
11 | // in the final binary.
12 |
13 | package vm
14 |
15 | var originalActivators = make(map[string]func(*JumpTable))
16 |
17 | func init() {
18 | keys := GetActivatorsEipNames()
19 |
20 | originalActivators = make(map[string]func(*JumpTable), len(keys))
21 |
22 | for _, k := range keys {
23 | originalActivators[k] = activators[k]
24 | }
25 | }
26 |
27 | // ResetActivators resets activators to the original go ethereum activators map
28 | func ResetActivators() {
29 | activators = make(map[string]func(*JumpTable))
30 | for k, v := range originalActivators {
31 | activators[k] = v
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/x/evm/core/vm/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2015 The go-ethereum Authors
2 | // This file is part of the go-ethereum library.
3 | //
4 | // The go-ethereum library is free software: you can redistribute it and/or modify
5 | // it under the terms of the GNU Lesser General Public License as published by
6 | // the Free Software Foundation, either version 3 of the License, or
7 | // (at your option) any later version.
8 | //
9 | // The go-ethereum library is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | // GNU Lesser General Public License for more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License
15 | // along with the go-ethereum library. If not, see .
16 |
17 | /*
18 | Package vm implements the Ethereum Virtual Machine.
19 |
20 | The vm package implements one EVM, a byte code VM. The BC (Byte Code) VM loops
21 | over a set of bytes and executes them according to the set of rules defined
22 | in the Ethereum yellow paper.
23 | */
24 | package vm
25 |
--------------------------------------------------------------------------------
/x/evm/core/vm/stack_table.go:
--------------------------------------------------------------------------------
1 | // Copyright 2017 The go-ethereum Authors
2 | // This file is part of the go-ethereum library.
3 | //
4 | // The go-ethereum library is free software: you can redistribute it and/or modify
5 | // it under the terms of the GNU Lesser General Public License as published by
6 | // the Free Software Foundation, either version 3 of the License, or
7 | // (at your option) any later version.
8 | //
9 | // The go-ethereum library is distributed in the hope that it will be useful,
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | // GNU Lesser General Public License for more details.
13 | //
14 | // You should have received a copy of the GNU Lesser General Public License
15 | // along with the go-ethereum library. If not, see .
16 |
17 | package vm
18 |
19 | import (
20 | "github.com/ethereum/go-ethereum/params"
21 | )
22 |
23 | func minSwapStack(n int) int {
24 | return minStack(n, n)
25 | }
26 |
27 | func maxSwapStack(n int) int {
28 | return maxStack(n, n)
29 | }
30 |
31 | func minDupStack(n int) int {
32 | return minStack(n, n+1)
33 | }
34 |
35 | func maxDupStack(n int) int {
36 | return maxStack(n, n+1)
37 | }
38 |
39 | func maxStack(pop, push int) int {
40 | return int(params.StackLimit) + pop - push
41 | }
42 |
43 | func minStack(pops, _ int) int {
44 | return pops
45 | }
46 |
--------------------------------------------------------------------------------
/x/evm/core/vm/testdata/precompiles/fail-blsMapG1.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "Input": "",
4 | "ExpectedError": "invalid input length",
5 | "Name": "bls_mapg1_empty_input"
6 | },
7 | {
8 | "Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
9 | "ExpectedError": "invalid input length",
10 | "Name": "bls_mapg1_short_input"
11 | },
12 | {
13 | "Input": "00000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
14 | "ExpectedError": "invalid field element top bytes",
15 | "Name": "bls_mapg1_top_bytes"
16 | },
17 | {
18 | "Input": "000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac",
19 | "ExpectedError": "must be less than modulus",
20 | "Name": "bls_mapg1_invalid_fq_element"
21 | }
22 | ]
--------------------------------------------------------------------------------
/x/evm/core/vm/testdata/precompiles/fail-blsMapG2.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "Input": "",
4 | "ExpectedError": "invalid input length",
5 | "Name": "bls_mapg2_empty_input"
6 | },
7 | {
8 | "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
9 | "ExpectedError": "invalid input length",
10 | "Name": "bls_mapg2_short_input"
11 | },
12 | {
13 | "Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
14 | "ExpectedError": "invalid field element top bytes",
15 | "Name": "bls_mapg2_top_bytes"
16 | },
17 | {
18 | "Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac",
19 | "ExpectedError": "must be less than modulus",
20 | "Name": "bls_mapg2_invalid_fq_element"
21 | }
22 | ]
--------------------------------------------------------------------------------
/x/evm/keeper/abci_test.go:
--------------------------------------------------------------------------------
1 | package keeper_test
2 |
3 | import (
4 | testkeyring "github.com/evmos/os/testutil/integration/os/keyring"
5 | "github.com/evmos/os/testutil/integration/os/network"
6 | evmtypes "github.com/evmos/os/x/evm/types"
7 | )
8 |
9 | func (suite *KeeperTestSuite) TestEndBlock() {
10 | keyring := testkeyring.New(2)
11 | unitNetwork := network.NewUnitTestNetwork(
12 | network.WithPreFundedAccounts(keyring.GetAllAccAddrs()...),
13 | )
14 | ctx := unitNetwork.GetContext()
15 | preEventManager := ctx.EventManager()
16 | suite.Require().Equal(0, len(preEventManager.Events()))
17 |
18 | err := unitNetwork.App.EVMKeeper.EndBlock(ctx)
19 | suite.Require().NoError(err)
20 |
21 | postEventManager := unitNetwork.GetContext().EventManager()
22 | // should emit 1 EventTypeBlockBloom event on EndBlock
23 | suite.Require().Equal(1, len(postEventManager.Events()))
24 | suite.Require().Equal(evmtypes.EventTypeBlockBloom, postEventManager.Events()[0].Type)
25 | }
26 |
--------------------------------------------------------------------------------
/x/evm/keeper/block_proposer.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package keeper
5 |
6 | import (
7 | errorsmod "cosmossdk.io/errors"
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
10 | "github.com/ethereum/go-ethereum/common"
11 | )
12 |
13 | // GetCoinbaseAddress returns the block proposer's validator operator address.
14 | func (k Keeper) GetCoinbaseAddress(ctx sdk.Context, proposerAddress sdk.ConsAddress) (common.Address, error) {
15 | validator, err := k.stakingKeeper.GetValidatorByConsAddr(ctx, GetProposerAddress(ctx, proposerAddress))
16 | if err != nil {
17 | return common.Address{}, errorsmod.Wrapf(
18 | stakingtypes.ErrNoValidatorFound,
19 | "failed to retrieve validator from block proposer address %s. Error: %s",
20 | proposerAddress.String(),
21 | err.Error(),
22 | )
23 | }
24 |
25 | coinbase := common.BytesToAddress([]byte(validator.GetOperator()))
26 | return coinbase, nil
27 | }
28 |
29 | // GetProposerAddress returns current block proposer's address when provided proposer address is empty.
30 | func GetProposerAddress(ctx sdk.Context, proposerAddress sdk.ConsAddress) sdk.ConsAddress {
31 | if len(proposerAddress) == 0 {
32 | proposerAddress = ctx.BlockHeader().ProposerAddress
33 | }
34 | return proposerAddress
35 | }
36 |
--------------------------------------------------------------------------------
/x/evm/keeper/params_benchmark_test.go:
--------------------------------------------------------------------------------
1 | package keeper_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/evmos/os/x/evm/types"
7 | )
8 |
9 | func BenchmarkSetParams(b *testing.B) {
10 | suite := KeeperTestSuite{}
11 | suite.SetupTest()
12 | params := types.DefaultParams()
13 |
14 | b.ReportAllocs()
15 | b.ResetTimer()
16 | for i := 0; i < b.N; i++ {
17 | _ = suite.network.App.EVMKeeper.SetParams(suite.network.GetContext(), params)
18 | }
19 | }
20 |
21 | func BenchmarkGetParams(b *testing.B) {
22 | suite := KeeperTestSuite{}
23 | suite.SetupTest()
24 |
25 | b.ReportAllocs()
26 | b.ResetTimer()
27 | for i := 0; i < b.N; i++ {
28 | _ = suite.network.App.EVMKeeper.GetParams(suite.network.GetContext())
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/x/evm/keeper/testdata/contracts.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package testdata
5 |
6 | import (
7 | contractutils "github.com/evmos/os/contracts/utils"
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | )
10 |
11 | func LoadERC20Contract() (evmtypes.CompiledContract, error) {
12 | return contractutils.LegacyLoadContractFromJSONFile("ERC20Contract.json")
13 | }
14 |
15 | func LoadMessageCallContract() (evmtypes.CompiledContract, error) {
16 | return contractutils.LegacyLoadContractFromJSONFile("MessageCallContract.json")
17 | }
18 |
--------------------------------------------------------------------------------
/x/evm/keeper/utils.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package keeper
5 |
6 | import (
7 | "cosmossdk.io/store/prefix"
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | "github.com/ethereum/go-ethereum/common"
10 | "github.com/evmos/os/x/evm/types"
11 | )
12 |
13 | // IsContract determines if the given address is a smart contract.
14 | func (k *Keeper) IsContract(ctx sdk.Context, addr common.Address) bool {
15 | store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixCodeHash)
16 | return store.Has(addr.Bytes())
17 | }
18 |
--------------------------------------------------------------------------------
/x/evm/types/access_list_test.go:
--------------------------------------------------------------------------------
1 | package types_test
2 |
3 | import (
4 | "github.com/ethereum/go-ethereum/common"
5 | ethtypes "github.com/ethereum/go-ethereum/core/types"
6 | "github.com/evmos/os/x/evm/types"
7 | )
8 |
9 | func (suite *TxDataTestSuite) TestTestNewAccessList() {
10 | testCases := []struct {
11 | name string
12 | ethAccessList *ethtypes.AccessList
13 | expAl types.AccessList
14 | }{
15 | {
16 | "ethAccessList is nil",
17 | nil,
18 | nil,
19 | },
20 | {
21 | "non-empty ethAccessList",
22 | ðtypes.AccessList{{Address: suite.addr, StorageKeys: []common.Hash{{0}}}},
23 | types.AccessList{{Address: suite.hexAddr, StorageKeys: []string{common.Hash{}.Hex()}}},
24 | },
25 | }
26 | for _, tc := range testCases {
27 | al := types.NewAccessList(tc.ethAccessList)
28 |
29 | suite.Require().Equal(tc.expAl, al)
30 | }
31 | }
32 |
33 | func (suite *TxDataTestSuite) TestAccessListToEthAccessList() {
34 | ethAccessList := ethtypes.AccessList{{Address: suite.addr, StorageKeys: []common.Hash{{0}}}}
35 | al := types.NewAccessList(ðAccessList)
36 | actual := al.ToEthAccessList()
37 |
38 | suite.Require().Equal(ðAccessList, actual)
39 | }
40 |
--------------------------------------------------------------------------------
/x/evm/types/call.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | type CallType int
6 |
7 | const (
8 | // RPC call type is used on requests to eth_estimateGas rpc API endpoint
9 | RPC CallType = iota + 1
10 | // Internal call type is used in case of smart contract methods calls
11 | Internal
12 | )
13 |
14 | // MaxPrecompileCalls is the maximum number of precompile
15 | // calls within a transaction. We want to limit this because
16 | // for each precompile tx we're creating a cached context
17 | const MaxPrecompileCalls uint8 = 7
18 |
--------------------------------------------------------------------------------
/x/evm/types/codec_test.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "testing"
5 |
6 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | type caseAny struct {
11 | name string
12 | any *codectypes.Any
13 | expPass bool
14 | }
15 |
16 | func TestPackTxData(t *testing.T) {
17 | testCases := []struct {
18 | name string
19 | txData TxData
20 | expPass bool
21 | }{
22 | {
23 | "access list tx",
24 | &AccessListTx{},
25 | true,
26 | },
27 | {
28 | "legacy tx",
29 | &LegacyTx{},
30 | true,
31 | },
32 | {
33 | "nil",
34 | nil,
35 | false,
36 | },
37 | }
38 |
39 | testCasesAny := []caseAny{}
40 |
41 | for _, tc := range testCases {
42 | txDataAny, err := PackTxData(tc.txData)
43 | if tc.expPass {
44 | require.NoError(t, err, tc.name)
45 | } else {
46 | require.Error(t, err, tc.name)
47 | }
48 |
49 | testCasesAny = append(testCasesAny, caseAny{tc.name, txDataAny, tc.expPass})
50 | }
51 |
52 | for i, tc := range testCasesAny {
53 | cs, err := UnpackTxData(tc.any)
54 | if tc.expPass {
55 | require.NoError(t, err, tc.name)
56 | require.Equal(t, testCases[i].txData, cs, tc.name)
57 | } else {
58 | require.Error(t, err, tc.name)
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/x/evm/types/compiled_contract_test.go:
--------------------------------------------------------------------------------
1 | package types_test
2 |
3 | import (
4 | "encoding/json"
5 | "os"
6 | "testing"
7 |
8 | evmtypes "github.com/evmos/os/x/evm/types"
9 | "github.com/stretchr/testify/require"
10 | )
11 |
12 | func TestHardhatCompiledContract(t *testing.T) {
13 | contents, err := os.ReadFile("testdata/SimpleContractHardhat.json")
14 | require.NoError(t, err, "failed to read file")
15 | require.NotEmpty(t, contents, "expected contents not to be empty")
16 |
17 | var hardhatContract evmtypes.HardhatCompiledContract
18 | err = json.Unmarshal(contents, &hardhatContract)
19 | require.NoError(t, err, "failed to unmarshal contract")
20 |
21 | require.Equal(t, hardhatContract.ContractName, "SimpleContract")
22 | require.Contains(t,
23 | hardhatContract.ABI.Methods,
24 | "setValue",
25 | "missing setValue method in contract ABI methods",
26 | )
27 |
28 | compiledContract, err := hardhatContract.ToCompiledContract()
29 | require.NoError(t, err, "failed to convert hardhat contract to compiled contract type")
30 | require.Equal(t, compiledContract.ABI, hardhatContract.ABI, "expected ABIs to be equal")
31 | require.NotEmpty(t, compiledContract.Bin, "expected bin data not to be empty")
32 | }
33 |
--------------------------------------------------------------------------------
/x/evm/types/events.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | // Evm module events
6 | const (
7 | EventTypeEthereumTx = TypeMsgEthereumTx
8 | EventTypeBlockBloom = "block_bloom"
9 | EventTypeTxLog = "tx_log"
10 | EventTypeFeeMarket = "evm_fee_market"
11 |
12 | AttributeKeyBaseFee = "base_fee"
13 | AttributeKeyContractAddress = "contract"
14 | AttributeKeyRecipient = "recipient"
15 | AttributeKeyTxHash = "txHash"
16 | AttributeKeyEthereumTxHash = "ethereumTxHash"
17 | AttributeKeyTxIndex = "txIndex"
18 | AttributeKeyTxGasUsed = "txGasUsed"
19 | AttributeKeyTxType = "txType"
20 | AttributeKeyTxLog = "txLog"
21 |
22 | // tx failed in eth vm execution
23 | AttributeKeyEthereumTxFailed = "ethereumTxFailed"
24 | AttributeValueCategory = ModuleName
25 | AttributeKeyEthereumBloom = "bloom"
26 |
27 | MetricKeyTransitionDB = "transition_db"
28 | MetricKeyStaticCall = "static_call"
29 | )
30 |
--------------------------------------------------------------------------------
/x/evm/types/query.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | import (
6 | codectypes "github.com/cosmos/cosmos-sdk/codec/types"
7 | )
8 |
9 | // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
10 | func (m QueryTraceTxRequest) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
11 | for _, msg := range m.Predecessors {
12 | if err := msg.UnpackInterfaces(unpacker); err != nil {
13 | return err
14 | }
15 | }
16 | return m.Msg.UnpackInterfaces(unpacker)
17 | }
18 |
19 | func (m QueryTraceBlockRequest) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
20 | for _, msg := range m.Txs {
21 | if err := msg.UnpackInterfaces(unpacker); err != nil {
22 | return err
23 | }
24 | }
25 | return nil
26 | }
27 |
28 | // Failed returns if the contract execution failed in vm errors
29 | func (egr EstimateGasResponse) Failed() bool {
30 | return len(egr.VmError) > 0
31 | }
32 |
--------------------------------------------------------------------------------
/x/evm/types/tracer_test.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/require"
7 | )
8 |
9 | func TestNewNoOpTracer(t *testing.T) {
10 | require.Equal(t, &NoOpTracer{}, NewNoOpTracer())
11 | }
12 |
--------------------------------------------------------------------------------
/x/evm/types/tx_types.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | import (
6 | gethtypes "github.com/ethereum/go-ethereum/core/types"
7 | )
8 |
9 | func GetTxTypeName(txType int) string {
10 | switch txType {
11 | case gethtypes.DynamicFeeTxType:
12 | return "DynamicFeeTxType"
13 | case gethtypes.LegacyTxType:
14 | return "LegacyTxType"
15 | case gethtypes.AccessListTxType:
16 | return "AccessListTxType"
17 | default:
18 | panic("unknown tx type")
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/x/feemarket/genesis.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package feemarket
4 |
5 | import (
6 | errorsmod "cosmossdk.io/errors"
7 | abci "github.com/cometbft/cometbft/abci/types"
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 |
10 | "github.com/evmos/os/x/feemarket/keeper"
11 | "github.com/evmos/os/x/feemarket/types"
12 | )
13 |
14 | // InitGenesis initializes genesis state based on exported genesis
15 | func InitGenesis(
16 | ctx sdk.Context,
17 | k keeper.Keeper,
18 | data types.GenesisState,
19 | ) []abci.ValidatorUpdate {
20 | err := k.SetParams(ctx, data.Params)
21 | if err != nil {
22 | panic(errorsmod.Wrap(err, "could not set parameters at genesis"))
23 | }
24 |
25 | k.SetBlockGasWanted(ctx, data.BlockGas)
26 |
27 | return []abci.ValidatorUpdate{}
28 | }
29 |
30 | // ExportGenesis exports genesis state of the fee market module
31 | func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState {
32 | return &types.GenesisState{
33 | Params: k.GetParams(ctx),
34 | BlockGas: k.GetBlockGasWanted(ctx),
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/x/feemarket/keeper/msg_server.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package keeper
4 |
5 | import (
6 | "context"
7 |
8 | errorsmod "cosmossdk.io/errors"
9 | sdk "github.com/cosmos/cosmos-sdk/types"
10 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
11 | "github.com/evmos/os/x/feemarket/types"
12 | )
13 |
14 | // UpdateParams implements the gRPC MsgServer interface. When an UpdateParams
15 | // proposal passes, it updates the module parameters. The update can only be
16 | // performed if the requested authority is the Cosmos SDK governance module
17 | // account.
18 | func (k *Keeper) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) {
19 | if k.authority.String() != req.Authority {
20 | return nil, errorsmod.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.authority.String(), req.Authority)
21 | }
22 |
23 | ctx := sdk.UnwrapSDKContext(goCtx)
24 | if err := k.SetParams(ctx, req.Params); err != nil {
25 | return nil, err
26 | }
27 |
28 | return &types.MsgUpdateParamsResponse{}, nil
29 | }
30 |
--------------------------------------------------------------------------------
/x/feemarket/keeper/msg_server_test.go:
--------------------------------------------------------------------------------
1 | package keeper_test
2 |
3 | import (
4 | "testing"
5 |
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
8 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
9 | "github.com/evmos/os/testutil/integration/os/network"
10 | "github.com/evmos/os/x/feemarket/types"
11 | "github.com/stretchr/testify/require"
12 | )
13 |
14 | func TestUpdateParams(t *testing.T) {
15 | var (
16 | nw *network.UnitTestNetwork
17 | ctx sdk.Context
18 | )
19 |
20 | testCases := []struct {
21 | name string
22 | request *types.MsgUpdateParams
23 | expectErr bool
24 | }{
25 | {
26 | name: "fail - invalid authority",
27 | request: &types.MsgUpdateParams{Authority: "foobar"},
28 | expectErr: true,
29 | },
30 | {
31 | name: "pass - valid Update msg",
32 | request: &types.MsgUpdateParams{
33 | Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(),
34 | Params: types.DefaultParams(),
35 | },
36 | expectErr: false,
37 | },
38 | }
39 |
40 | for _, tc := range testCases {
41 | t.Run(tc.name, func(t *testing.T) {
42 | // reset network and context
43 | nw = network.NewUnitTestNetwork()
44 | ctx = nw.GetContext()
45 |
46 | _, err := nw.App.FeeMarketKeeper.UpdateParams(ctx, tc.request)
47 | if tc.expectErr {
48 | require.Error(t, err)
49 | } else {
50 | require.NoError(t, err)
51 | }
52 | })
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/x/feemarket/keeper/setup_test.go:
--------------------------------------------------------------------------------
1 | package keeper_test
2 |
3 | import (
4 | "github.com/cosmos/cosmos-sdk/baseapp"
5 | "github.com/evmos/os/testutil/integration/os/factory"
6 | "github.com/evmos/os/testutil/integration/os/grpc"
7 | testkeyring "github.com/evmos/os/testutil/integration/os/keyring"
8 | "github.com/evmos/os/testutil/integration/os/network"
9 | "github.com/stretchr/testify/suite"
10 | )
11 |
12 | type KeeperTestSuite struct {
13 | suite.Suite
14 |
15 | network *network.UnitTestNetwork
16 | factory factory.TxFactory
17 | grpcHandler grpc.Handler
18 | keyring testkeyring.Keyring
19 |
20 | denom string
21 | }
22 |
23 | // SetupTest setup test environment
24 | func (suite *KeeperTestSuite) SetupTest() {
25 | keyring := testkeyring.New(2)
26 | nw := network.NewUnitTestNetwork(
27 | network.WithPreFundedAccounts(keyring.GetAllAccAddrs()...),
28 | network.WithCustomBaseAppOpts(baseapp.SetMinGasPrices("10aevmos")),
29 | )
30 | grpcHandler := grpc.NewIntegrationHandler(nw)
31 | txFactory := factory.New(nw, grpcHandler)
32 |
33 | ctx := nw.GetContext()
34 | sk := nw.App.StakingKeeper
35 | bondDenom, err := sk.BondDenom(ctx)
36 | if err != nil {
37 | panic(err)
38 | }
39 |
40 | suite.denom = bondDenom
41 | suite.factory = txFactory
42 | suite.grpcHandler = grpcHandler
43 | suite.keyring = keyring
44 | suite.network = nw
45 | }
46 |
--------------------------------------------------------------------------------
/x/feemarket/types/events.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | // feemarket module events
6 | const (
7 | EventTypeFeeMarket = "fee_market"
8 |
9 | AttributeKeyBaseFee = "base_fee"
10 | )
11 |
--------------------------------------------------------------------------------
/x/feemarket/types/genesis.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | // DefaultGenesisState sets default fee market genesis state.
6 | func DefaultGenesisState() *GenesisState {
7 | return &GenesisState{
8 | Params: DefaultParams(),
9 | BlockGas: 0,
10 | }
11 | }
12 |
13 | // NewGenesisState creates a new genesis state.
14 | func NewGenesisState(params Params, blockGas uint64) *GenesisState {
15 | return &GenesisState{
16 | Params: params,
17 | BlockGas: blockGas,
18 | }
19 | }
20 |
21 | // Validate performs basic genesis state validation returning an error upon any
22 | // failure.
23 | func (gs GenesisState) Validate() error {
24 | return gs.Params.Validate()
25 | }
26 |
--------------------------------------------------------------------------------
/x/feemarket/types/genesis_test.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/suite"
7 | )
8 |
9 | type GenesisTestSuite struct {
10 | suite.Suite
11 | }
12 |
13 | func TestGenesisTestSuite(t *testing.T) {
14 | suite.Run(t, new(GenesisTestSuite))
15 | }
16 |
17 | func (suite *GenesisTestSuite) TestValidateGenesis() {
18 | testCases := []struct {
19 | name string
20 | genState *GenesisState
21 | expPass bool
22 | }{
23 | {
24 | "default",
25 | DefaultGenesisState(),
26 | true,
27 | },
28 | {
29 | "valid genesis",
30 | &GenesisState{
31 | DefaultParams(),
32 | uint64(1),
33 | },
34 | true,
35 | },
36 | {
37 | "valid New genesis",
38 | NewGenesisState(
39 | DefaultParams(),
40 | uint64(1),
41 | ),
42 | true,
43 | },
44 | {
45 | "empty genesis",
46 | &GenesisState{
47 | Params: Params{},
48 | BlockGas: 0,
49 | },
50 | false,
51 | },
52 | }
53 |
54 | for _, tc := range testCases {
55 | err := tc.genState.Validate()
56 | if tc.expPass {
57 | suite.Require().NoError(err, tc.name)
58 | } else {
59 | suite.Require().Error(err, tc.name)
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/x/feemarket/types/interfaces.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | import (
6 | sdk "github.com/cosmos/cosmos-sdk/types"
7 | paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
8 | )
9 |
10 | type (
11 | LegacyParams = paramtypes.ParamSet
12 | // Subspace defines an interface that implements the legacy Cosmos SDK x/params Subspace type.
13 | // NOTE: This is used solely for migration of the Cosmos SDK x/params managed parameters.
14 | Subspace interface {
15 | GetParamSetIfExists(ctx sdk.Context, ps LegacyParams)
16 | }
17 | )
18 |
--------------------------------------------------------------------------------
/x/feemarket/types/keys.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | const (
6 | // ModuleName string name of module
7 | ModuleName = "feemarket"
8 |
9 | // StoreKey key for base fee and block gas used.
10 | // The Fee Market module should use a prefix store.
11 | StoreKey = ModuleName
12 |
13 | // RouterKey uses module name for routing
14 | RouterKey = ModuleName
15 |
16 | // TransientKey is the key to access the FeeMarket transient store, that is reset
17 | // during the Commit phase.
18 | TransientKey = "transient_" + ModuleName
19 | )
20 |
21 | // prefix bytes for the feemarket persistent store
22 | const (
23 | prefixBlockGasWanted = iota + 1
24 | deprecatedPrefixBaseFee // unused
25 | )
26 |
27 | const (
28 | prefixTransientBlockGasUsed = iota + 1
29 | )
30 |
31 | // KVStore key prefixes
32 | var (
33 | KeyPrefixBlockGasWanted = []byte{prefixBlockGasWanted}
34 | )
35 |
36 | // Transient Store key prefixes
37 | var (
38 | KeyPrefixTransientBlockGasWanted = []byte{prefixTransientBlockGasUsed}
39 | )
40 |
--------------------------------------------------------------------------------
/x/feemarket/types/msg.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package types
5 |
6 | import (
7 | errorsmod "cosmossdk.io/errors"
8 | sdk "github.com/cosmos/cosmos-sdk/types"
9 | )
10 |
11 | var _ sdk.Msg = &MsgUpdateParams{}
12 |
13 | // ValidateBasic does a sanity check of the provided data
14 | func (m *MsgUpdateParams) ValidateBasic() error {
15 | if _, err := sdk.AccAddressFromBech32(m.Authority); err != nil {
16 | return errorsmod.Wrap(err, "invalid authority address")
17 | }
18 |
19 | return m.Params.Validate()
20 | }
21 |
22 | // GetSignBytes implements the LegacyMsg interface.
23 | func (m MsgUpdateParams) GetSignBytes() []byte {
24 | return sdk.MustSortJSON(AminoCdc.MustMarshalJSON(&m))
25 | }
26 |
--------------------------------------------------------------------------------
/x/feemarket/types/msg_test.go:
--------------------------------------------------------------------------------
1 | package types
2 |
3 | import (
4 | "testing"
5 |
6 | authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
7 | govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
8 | "github.com/stretchr/testify/suite"
9 | )
10 |
11 | type MsgsTestSuite struct {
12 | suite.Suite
13 | }
14 |
15 | func TestMsgsTestSuite(t *testing.T) {
16 | suite.Run(t, new(MsgsTestSuite))
17 | }
18 |
19 | func (suite *MsgsTestSuite) TestMsgUpdateValidateBasic() {
20 | testCases := []struct {
21 | name string
22 | msgUpdate *MsgUpdateParams
23 | expPass bool
24 | }{
25 | {
26 | "fail - invalid authority address",
27 | &MsgUpdateParams{
28 | Authority: "invalid",
29 | Params: DefaultParams(),
30 | },
31 | false,
32 | },
33 | {
34 | "pass - valid msg",
35 | &MsgUpdateParams{
36 | Authority: authtypes.NewModuleAddress(govtypes.ModuleName).String(),
37 | Params: DefaultParams(),
38 | },
39 | true,
40 | },
41 | }
42 |
43 | for _, tc := range testCases {
44 | suite.Run(tc.name, func() {
45 | err := tc.msgUpdate.ValidateBasic()
46 | if tc.expPass {
47 | suite.NoError(err)
48 | } else {
49 | suite.Error(err)
50 | }
51 | })
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/x/ibc/transfer/ibc_module.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package transfer
5 |
6 | import (
7 | ibctransfer "github.com/cosmos/ibc-go/v8/modules/apps/transfer"
8 | porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types"
9 | "github.com/evmos/os/x/ibc/transfer/keeper"
10 | )
11 |
12 | var _ porttypes.IBCModule = IBCModule{}
13 |
14 | // IBCModule implements the ICS26 interface for transfer given the transfer keeper.
15 | type IBCModule struct {
16 | *ibctransfer.IBCModule
17 | }
18 |
19 | // NewIBCModule creates a new IBCModule given the keeper
20 | func NewIBCModule(k keeper.Keeper) IBCModule {
21 | transferModule := ibctransfer.NewIBCModule(*k.Keeper)
22 | return IBCModule{
23 | IBCModule: &transferModule,
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/x/ibc/transfer/types/channels.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 | package types
4 |
5 | // Osmosis channels
6 | const (
7 | OsmosisTestnetChannelID = "channel-215"
8 | OsmosisMainnetChannelID = "channel-0"
9 | )
10 |
11 | // Stride channels
12 | const (
13 | StrideTestnetChannelID = "channel-25"
14 | StrideMainnetChannelID = "channel-25"
15 | )
16 |
--------------------------------------------------------------------------------
/x/ibc/transfer/types/interfaces.go:
--------------------------------------------------------------------------------
1 | // Copyright Tharsis Labs Ltd.(Evmos)
2 | // SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)
3 |
4 | package types
5 |
6 | import (
7 | "context"
8 |
9 | sdk "github.com/cosmos/cosmos-sdk/types"
10 |
11 | transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
12 |
13 | erc20types "github.com/evmos/os/x/erc20/types"
14 | )
15 |
16 | // AccountKeeper defines the expected interface needed to retrieve account info.
17 | type AccountKeeper interface {
18 | transfertypes.AccountKeeper
19 | GetAccount(context.Context, sdk.AccAddress) sdk.AccountI
20 | }
21 |
22 | // BankKeeper defines the expected interface needed to check balances and send coins.
23 | type BankKeeper interface {
24 | transfertypes.BankKeeper
25 | GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin
26 | }
27 |
28 | // ERC20Keeper defines the expected ERC20 keeper interface for supporting
29 | // ERC20 token transfers via IBC.
30 | type ERC20Keeper interface {
31 | IsERC20Enabled(ctx sdk.Context) bool
32 | GetTokenPairID(ctx sdk.Context, token string) []byte
33 | GetTokenPair(ctx sdk.Context, id []byte) (erc20types.TokenPair, bool)
34 | ConvertERC20(ctx context.Context, msg *erc20types.MsgConvertERC20) (*erc20types.MsgConvertERC20Response, error)
35 | }
36 |
--------------------------------------------------------------------------------