From 812972c8322179e60dcb27035fb177f8af795d62 Mon Sep 17 00:00:00 2001 From: Shawn <44221603+shaspitz@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:17:58 -0800 Subject: [PATCH] separate precompiles for mint/burn --- core/vm/contracts.go | 18 +++++++++----- core/vm/contracts_with_ctx.go | 45 ++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 33a5e0f916..01cf709671 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -49,7 +49,8 @@ var PrecompiledContractsHomestead = map[common.Address]PrecompiledContractWithCt common.BytesToAddress([]byte{2}): precompileWrapper{&sha256hash{}}, common.BytesToAddress([]byte{3}): precompileWrapper{&ripemd160hash{}}, common.BytesToAddress([]byte{4}): precompileWrapper{&dataCopy{}}, - common.BytesToAddress([]byte{0x89}): &transfer{}, + common.BytesToAddress([]byte{0x89}): &mint{}, + common.BytesToAddress([]byte{0x90}): &burn{}, } // PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum @@ -63,7 +64,8 @@ var PrecompiledContractsByzantium = map[common.Address]PrecompiledContractWithCt common.BytesToAddress([]byte{6}): precompileWrapper{&bn256AddByzantium{}}, common.BytesToAddress([]byte{7}): precompileWrapper{&bn256ScalarMulByzantium{}}, common.BytesToAddress([]byte{8}): precompileWrapper{&bn256PairingByzantium{}}, - common.BytesToAddress([]byte{0x89}): &transfer{}, + common.BytesToAddress([]byte{0x89}): &mint{}, + common.BytesToAddress([]byte{0x90}): &burn{}, } // PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum @@ -78,7 +80,8 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContractWithCtx common.BytesToAddress([]byte{7}): precompileWrapper{&bn256ScalarMulIstanbul{}}, common.BytesToAddress([]byte{8}): precompileWrapper{&bn256PairingIstanbul{}}, common.BytesToAddress([]byte{9}): precompileWrapper{&blake2F{}}, - common.BytesToAddress([]byte{0x89}): &transfer{}, + common.BytesToAddress([]byte{0x89}): &mint{}, + common.BytesToAddress([]byte{0x90}): &burn{}, } // PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum @@ -93,7 +96,8 @@ var PrecompiledContractsBerlin = map[common.Address]PrecompiledContractWithCtx{ common.BytesToAddress([]byte{7}): precompileWrapper{&bn256ScalarMulIstanbul{}}, common.BytesToAddress([]byte{8}): precompileWrapper{&bn256PairingIstanbul{}}, common.BytesToAddress([]byte{9}): precompileWrapper{&blake2F{}}, - common.BytesToAddress([]byte{0x89}): &transfer{}, + common.BytesToAddress([]byte{0x89}): &mint{}, + common.BytesToAddress([]byte{0x90}): &burn{}, } // PrecompiledContractsCancun contains the default set of pre-compiled Ethereum @@ -109,7 +113,8 @@ var PrecompiledContractsCancun = map[common.Address]PrecompiledContractWithCtx{ common.BytesToAddress([]byte{8}): precompileWrapper{&bn256PairingIstanbul{}}, common.BytesToAddress([]byte{9}): precompileWrapper{&blake2F{}}, common.BytesToAddress([]byte{0x0a}): precompileWrapper{&kzgPointEvaluation{}}, - common.BytesToAddress([]byte{0x89}): &transfer{}, + common.BytesToAddress([]byte{0x89}): &mint{}, + common.BytesToAddress([]byte{0x90}): &burn{}, } // PrecompiledContractsBLS contains the set of pre-compiled Ethereum @@ -124,7 +129,8 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContractWithCtx{ common.BytesToAddress([]byte{16}): precompileWrapper{&bls12381Pairing{}}, common.BytesToAddress([]byte{17}): precompileWrapper{&bls12381MapG1{}}, common.BytesToAddress([]byte{18}): precompileWrapper{&bls12381MapG2{}}, - common.BytesToAddress([]byte{0x89}): &transfer{}, + common.BytesToAddress([]byte{0x89}): &mint{}, + common.BytesToAddress([]byte{0x90}): &burn{}, } var ( diff --git a/core/vm/contracts_with_ctx.go b/core/vm/contracts_with_ctx.go index 93e685c83c..8b36f91b33 100644 --- a/core/vm/contracts_with_ctx.go +++ b/core/vm/contracts_with_ctx.go @@ -69,20 +69,18 @@ var mockEVM = &EVM{ TxContext: vmTxCtx, } -// Native transfer precompile to make bridging to native token possible. -type transfer struct{} +// Native token mint precompile to make bridging to native token possible. +type mint struct{} -func (c *transfer) RequiredGas(input []byte) uint64 { +func (c *mint) RequiredGas(input []byte) uint64 { // TODO: determine appropriate gas cost return 100 } -func (c *transfer) Run(input []byte, ctx *precompileContext) ([]byte, error) { +func (c *mint) Run(input []byte, ctx *precompileContext) ([]byte, error) { // TODO: filter out non-allowed callers - - // From - _ = common.BytesToAddress(input[0:32]) + _ = common.BytesToAddress(input[0:32]) // From to := common.BytesToAddress(input[32:64]) @@ -95,10 +93,35 @@ func (c *transfer) Run(input []byte, ctx *precompileContext) ([]byte, error) { // Mint case: Create native token out of thin air ctx.evm.StateDB.AddBalance(to, value) - // if !ctx.CanTransfer(ctx.evm.StateDB, from, value) { - // return nil, ErrInsufficientBalance - // } - // ctx.Transfer(ctx.evm, from, to, value) + return input, nil +} + +// Native token burn precompile to make bridging back to L1 possible. +type burn struct{} + +func (c *burn) RequiredGas(input []byte) uint64 { + // TODO: determine appropriate gas cost + return 100 +} + +func (c *burn) Run(input []byte, ctx *precompileContext) ([]byte, error) { + + // TODO: filter out non-allowed callers + _ = common.BytesToAddress(input[0:32]) // From + + // Address to get their tokens burned + addrReqTokenBurn := common.BytesToAddress(input[32:64]) + + var parsed bool + value, parsed := math.ParseBig256(hexutil.Encode(input[64:96])) + if !parsed { + return nil, fmt.Errorf("Error parsing transfer: unable to parse value from " + hexutil.Encode(input[64:96])) + } + + if !ctx.CanTransfer(ctx.evm.StateDB, addrReqTokenBurn, value) { + return nil, ErrInsufficientBalance + } + ctx.evm.StateDB.SubBalance(addrReqTokenBurn, value) return input, nil }