Skip to content

Commit

Permalink
feat(evm): Deduct a fee during the creation of a FunToken mapping. Im…
Browse files Browse the repository at this point in the history
…plemented by `deductCreateFunTokenFee` inside of the `eth.evm.v1.MsgCreateFunToken` transaction. (#1963)

* docs,refactor(evm): more function docs and better code organization

* add create_funtoken_fee to evm.Params

* chore: changelog

* chore: fix changelog PR number

* chore: revert merge conflict change

* chore: changelog typo

* chore: typo
  • Loading branch information
Unique-Divine authored Jul 12, 2024
1 parent 8970a6c commit fc1edd9
Show file tree
Hide file tree
Showing 21 changed files with 540 additions and 382 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#1960](https://github.com/NibiruChain/nibiru/pull/1960) - test(network): graceful cleanup for more consistent CI runs
- [#1961](https://github.com/NibiruChain/nibiru/pull/1961) - chore(test): reverted funtoken precompile test back to the isolated state
- [#1962](https://github.com/NibiruChain/nibiru/pull/1962) - chore(evm): code cleanup, unused code, typos, styles, warnings
- [#1963](https://github.com/NibiruChain/nibiru/pull/1963) - feat(evm): Deduct a fee during the creation of a FunToken mapping. Implemented by `deductCreateFunTokenFee` inside of the `eth.evm.v1.MsgCreateFunToken` transaction.

#### Dapp modules: perp, spot, oracle, etc

Expand Down
14 changes: 12 additions & 2 deletions proto/eth/evm/v1/evm.proto
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ message Params {
// evm_denom represents the token denomination used to run the EVM state
// transitions.
string evm_denom = 1 [(gogoproto.moretags) = "yaml:\"evm_denom\""];
// enable_create toggles state transitions that use the vm.Create function
// enable_create: Enables contract creation by allowing for state transitions
// that use the "vm.Create" function
bool enable_create = 2 [(gogoproto.moretags) = "yaml:\"enable_create\""];
// enable_call toggles state transitions that use the vm.Call function
// enable_call: Enables contract calls by allowing for state transitions that
// use the "vm.Call" function
bool enable_call = 3 [(gogoproto.moretags) = "yaml:\"enable_call\""];
// extra_eips defines the additional EIPs for the vm.Config
repeated int64 extra_eips = 4 [(gogoproto.customname) = "ExtraEIPs", (gogoproto.moretags) = "yaml:\"extra_eips\""];
Expand All @@ -48,6 +50,14 @@ message Params {
repeated string active_precompiles = 7;
// evm_channels is the list of channel identifiers from EVM compatible chains
repeated string evm_channels = 8 [(gogoproto.customname) = "EVMChannels"];

// Fee deducted and burned when calling "CreateFunToken" in units of
// "evm_denom".
string create_funtoken_fee = 9 [
(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false
];

}

// State represents a single Storage key value pair item.
Expand Down
2 changes: 1 addition & 1 deletion proto/eth/evm/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ message MsgUpdateParams {

// params defines the x/evm parameters to update.
// NOTE: All parameters must be supplied.
Params params = 2 [(gogoproto.nullable) = false];
eth.evm.v1.Params params = 2 [(gogoproto.nullable) = false];
}

// MsgUpdateParamsResponse defines the response structure for executing a
Expand Down
5 changes: 3 additions & 2 deletions x/common/testutil/testnetwork/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -593,14 +593,15 @@ func (n *Network) Cleanup() {

waitGroup.Wait()

// TODO: Is there a cleaner way to do this with a synchronous check?
// TODO: Is there a cleaner way to do this with a guarnteed synchronous on
// each "Validator.tmNode"?
// https://github.com/NibiruChain/nibiru/issues/1955

// Give a brief pause for things to finish closing in other processes.
// Hopefully this helps with the address-in-use errors.
// Timeout of 100ms chosen randomly.
// Timeout of 250ms chosen because 100ms was not enough. | 2024-07-02
maxRetries := 5
maxRetries := 20
stopped := false
for i := 0; i < maxRetries; i++ {
if ValidatorsStopped(n.Validators) {
Expand Down
8 changes: 6 additions & 2 deletions x/common/testutil/testnetwork/validator_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,12 @@ func stopValidatorNode(v *Validator) {
// accepting new connections and RPCs and blocks until all the pending RPCs are
// finished.
v.grpc.GracefulStop()
if v.grpcWeb != nil {
_ = v.grpcWeb.Close()
}

if v.grpcWeb != nil {
err := v.grpcWeb.Close()
if err != nil {
v.Logger.Logf("❌ Error closing the gRPC web server: %w", err)
}
}

Expand Down
21 changes: 8 additions & 13 deletions x/evm/embeds/ERC20Minter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,20 @@ import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @dev {ERC20} token, including:
*
* - an "owner" that can mint tokens
* - ability for holders to burn (destroy) their tokens
* - a minter role that allows for token minting (creation)
*
* The contract owner is set automatically in the constructor as the
* deployer due to "Ownable".
*
* The Context contract is inherited indirectly through "ERC20" and "Ownable".
*
* The account that deploys the contract will be able to mint and burn tokens.
*/
contract ERC20Minter is ERC20, ERC20Burnable, Ownable {
uint8 private _decimals;

/**
* @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` to the
* account that deploys the contract and customizes tokens decimals
* @dev Grants "owner" status to the account that deploys the contract and
* customizes tokens decimals.
*
* See {ERC20-constructor}.
*/
Expand Down Expand Up @@ -52,24 +50,21 @@ contract ERC20Minter is ERC20, ERC20Burnable, Ownable {
*
* See {ERC20-_mint}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function mint(address to, uint256 amount) public virtual onlyOwner {
_mint(to, amount);
}

/**
* @dev Destroys `amount` new tokens for `to`.
* @dev Destroys `amount` new tokens for `to`. Suitable when the contract owner
* should have authority to burn tokens from an account directly, such as in
* the case of regulatory compliance, or actions selected via
* decentralized governance.
*
* See {ERC20-_burn}.
*
* Requirements:
*
* - the caller must have the `MINTER_ROLE`.
*/
function burnCoins(address from, uint256 amount) public virtual onlyOwner {
function burnFromAuthority(address from, uint256 amount) public virtual onlyOwner {
_burn(from, amount);
}

Expand Down
2 changes: 1 addition & 1 deletion x/evm/embeds/ERC20MinterCompiled.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
"type": "uint256"
}
],
"name": "burnCoins",
"name": "burnFromAuthority",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
Expand Down
5 changes: 5 additions & 0 deletions x/evm/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
)

// Errors related to ERC20 calls and FunToken mappings.
const (
ErrOwnable = "Ownable: caller is not the owner"
)

const (
codeErrInvalidState = uint32(iota) + 2 // NOTE: code 1 is reserved for internal errors
codeErrZeroAddress
Expand Down
Loading

0 comments on commit fc1edd9

Please sign in to comment.