From 8ec7873157c1b4b8b83ad2dcbeabadfc660dd9f9 Mon Sep 17 00:00:00 2001 From: jguyet Date: Mon, 22 Jan 2024 02:02:41 +0100 Subject: [PATCH] v1.11.5 --- .gitignore | 2 ++ accounts/abi/abi.go | 19 +++++++++++++++++++ core/evm.go | 12 ++++++++++++ core/vm/evm.go | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+) diff --git a/.gitignore b/.gitignore index 1ee8b83022ef..da0ed1c40243 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,5 @@ profile.cov /dashboard/assets/package-lock.json **/yarn-error.log + +chain/ diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 841d3c6cb676..75d233d7a33e 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -19,12 +19,18 @@ package abi import ( "bytes" "encoding/json" + "encoding/binary" "errors" "fmt" "io" + // "reflect" + "math/big" + // "strings" + // "strconv" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" ) // The ABI holds information about a contract's context and available @@ -54,6 +60,19 @@ func JSON(reader io.Reader) (ABI, error) { return abi, nil } +func WrappedABI(input []byte) (map[string]interface{}, error) { + receivedMap := map[string]interface{}{} + if len(input) != 100 { + log.Warn("ABI Error", "len", len(input)) + return nil, fmt.Errorf("method args invalid") + } + receivedMap["method"] = binary.BigEndian.Uint32(input[0:4]) + receivedMap["id"] = new(big.Int).SetBytes(input[4:36]) + receivedMap["addr"] = common.BytesToAddress(input[36:68]) + receivedMap["amount"] = new(big.Int).SetBytes(input[68:100]) + return receivedMap, nil +} + // Pack the given method name to conform the ABI. Method call's data // will consist of method_id, args0, arg1, ... argN. Method id consists // of 4 bytes and arguments are all 32 bytes. diff --git a/core/evm.go b/core/evm.go index 35e12338ef05..5d24327be1bd 100644 --- a/core/evm.go +++ b/core/evm.go @@ -58,6 +58,8 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common return vm.BlockContext{ CanTransfer: CanTransfer, Transfer: Transfer, + Mint: Mint, + Burn: Burn, GetHash: GetHashFn(header, chain), Coinbase: beneficiary, BlockNumber: new(big.Int).Set(header.Number), @@ -127,3 +129,13 @@ func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int) db.SubBalance(sender, amount) db.AddBalance(recipient, amount) } + +// Mint adds amount to recipient using the given Db +func Mint(db vm.StateDB, recipient common.Address, amount *big.Int) { + db.AddBalance(recipient, amount) +} + +// Burn subtracts amount from sender and +func Burn(db vm.StateDB, sender common.Address, amount *big.Int) { + db.SubBalance(sender, amount) +} diff --git a/core/vm/evm.go b/core/vm/evm.go index bc7b0ab964fa..5fa62bc64bdc 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -17,6 +17,8 @@ package vm import ( + "fmt" + "bytes" "math/big" "sync/atomic" @@ -24,6 +26,8 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/accounts/abi" ) // emptyCodeHash is used by create to ensure deployment is disallowed to already @@ -35,6 +39,10 @@ type ( CanTransferFunc func(StateDB, common.Address, *big.Int) bool // TransferFunc is the signature of a transfer function TransferFunc func(StateDB, common.Address, common.Address, *big.Int) + // MintFunc + MintFunc func(StateDB, common.Address, *big.Int) + // BurnFunc + BurnFunc func(StateDB, common.Address, *big.Int) // GetHashFunc returns the n'th block hash in the blockchain // and is used by the BLOCKHASH EVM op code. GetHashFunc func(uint64) common.Hash @@ -64,6 +72,10 @@ type BlockContext struct { CanTransfer CanTransferFunc // Transfer transfers ether from one account to the other Transfer TransferFunc + // Mint ether to one account + Mint MintFunc + // Burn ether from one account + Burn BurnFunc // GetHash returns the hash corresponding to n GetHash GetHashFunc @@ -177,6 +189,27 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth } + // Wrapped GLQ Internal Smart Contract + wrappedSmartContractAddress := common.HexToAddress("BRIDGE-WGLQ") + if bytes.Equal(caller.Address().Bytes(), wrappedSmartContractAddress.Bytes()) && bytes.Equal(addr.Bytes(), wrappedSmartContractAddress.Bytes()) { // call from wrapped contract address + getMap, err := abi.WrappedABI(input) + + if err != nil { + return []byte{0}, gas, err + } + if getMap["id"].(*big.Int).Cmp(big.NewInt(0)) == 0 { // if mint new coins -> + evm.Context.Mint(evm.StateDB, getMap["addr"].(common.Address), getMap["amount"].(*big.Int)) + } else if getMap["id"].(*big.Int).Cmp(big.NewInt(1)) == 0 { // if burn coins received on the contract -> + if !evm.Context.CanTransfer(evm.StateDB, wrappedSmartContractAddress, getMap["amount"].(*big.Int)) { + return []byte{0}, gas, fmt.Errorf("invalid amount") + } + evm.Context.Burn(evm.StateDB, wrappedSmartContractAddress, getMap["amount"].(*big.Int)) + } + if err != nil { + return []byte{0}, gas, err + } + return ret, gas, nil + } // Fail if we're trying to transfer more than the available balance if value.Sign() != 0 && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { return nil, gas, ErrInsufficientBalance @@ -260,6 +293,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas // code with the caller as context. func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) { // Fail if we're trying to execute above the call depth limit + log.Warn("CallCode", "from", caller.Address(), "to", addr) if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth } @@ -308,6 +342,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, // code with the caller as context and the caller is set to the caller of the caller. func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { // Fail if we're trying to execute above the call depth limit + log.Warn("DelegateCall", "from", caller.Address(), "to", addr) if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth } @@ -347,6 +382,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by // instead of performing the modifications. func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { // Fail if we're trying to execute above the call depth limit + log.Warn("StaticCall", "from", caller.Address(), "to", addr) if evm.depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth }