From 70b6e5efc53b2e26c653bb01518f573a033c2a8e Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Wed, 30 Oct 2024 04:13:02 -0500 Subject: [PATCH] chore: merge conflicts --- app/evmante/evmante_can_transfer.go | 3 +- .../TestNativeSendThenPrecompileSend.json | 4 +- .../TestNativeSendThenPrecompileSend.sol | 21 +-- x/evm/evmtest/erc20.go | 16 +++ x/evm/keeper/bank_extension.go | 25 ++-- x/evm/keeper/erc20.go | 4 +- x/evm/keeper/funtoken_from_coin_test.go | 125 ++++++++++++------ x/evm/keeper/msg_server.go | 1 - x/evm/keeper/statedb.go | 2 +- x/evm/precompile/funtoken.go | 80 +++++++++-- x/evm/statedb/statedb.go | 4 - 11 files changed, 198 insertions(+), 87 deletions(-) diff --git a/app/evmante/evmante_can_transfer.go b/app/evmante/evmante_can_transfer.go index 8af24d2f2..0f8cd0d06 100644 --- a/app/evmante/evmante_can_transfer.go +++ b/app/evmante/evmante_can_transfer.go @@ -72,9 +72,8 @@ func (ctd CanTransferDecorator) AnteHandle( BaseFeeWei: baseFeeWeiPerGas, } - stateDB := statedb.New( + stateDB := ctd.NewStateDB( ctx, - ctd.EVMKeeper, statedb.NewEmptyTxConfig(gethcommon.BytesToHash(ctx.HeaderHash().Bytes())), ) evmInstance := ctd.EVMKeeper.NewEVM(ctx, coreMsg, cfg, evm.NewNoOpTracer(), stateDB) diff --git a/x/evm/embeds/artifacts/contracts/TestNativeSendThenPrecompileSend.sol/TestNativeSendThenPrecompileSend.json b/x/evm/embeds/artifacts/contracts/TestNativeSendThenPrecompileSend.sol/TestNativeSendThenPrecompileSend.json index 5b0046040..e4a2ccfb1 100644 --- a/x/evm/embeds/artifacts/contracts/TestNativeSendThenPrecompileSend.sol/TestNativeSendThenPrecompileSend.json +++ b/x/evm/embeds/artifacts/contracts/TestNativeSendThenPrecompileSend.sol/TestNativeSendThenPrecompileSend.json @@ -43,8 +43,8 @@ "type": "function" } ], - "bytecode": "0x608060405234801561001057600080fd5b50604051610877380380610877833981810160405281019061003291906100db565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610108565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100a88261007d565b9050919050565b6100b88161009d565b81146100c357600080fd5b50565b6000815190506100d5816100af565b92915050565b6000602082840312156100f1576100f0610078565b5b60006100ff848285016100c6565b91505092915050565b610760806101176000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a4de557414610030575b600080fd5b61004a6004803603810190610045919061043c565b61004c565b005b60008473ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f193505050509050806100c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bc9061051c565b60405180910390fd5b600061080073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168486604051602401610115939291906105da565b6040516020818303038152906040527f03003bc5000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161019f919061065f565b6000604051808303816000865af19150503d80600081146101dc576040519150601f19603f3d011682016040523d82523d6000602084013e6101e1565b606091505b50509050806040516020016101f5906106f3565b60405160208183030381529060405290610245576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161023c9190610708565b60405180910390fd5b50505050505050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061028d82610262565b9050919050565b61029d81610282565b81146102a857600080fd5b50565b6000813590506102ba81610294565b92915050565b6000819050919050565b6102d3816102c0565b81146102de57600080fd5b50565b6000813590506102f0816102ca565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61034982610300565b810181811067ffffffffffffffff8211171561036857610367610311565b5b80604052505050565b600061037b61024e565b90506103878282610340565b919050565b600067ffffffffffffffff8211156103a7576103a6610311565b5b6103b082610300565b9050602081019050919050565b82818337600083830152505050565b60006103df6103da8461038c565b610371565b9050828152602081018484840111156103fb576103fa6102fb565b5b6104068482856103bd565b509392505050565b600082601f830112610423576104226102f6565b5b81356104338482602086016103cc565b91505092915050565b6000806000806080858703121561045657610455610258565b5b6000610464878288016102ab565b9450506020610475878288016102e1565b935050604085013567ffffffffffffffff8111156104965761049561025d565b5b6104a28782880161040e565b92505060606104b3878288016102e1565b91505092959194509250565b600082825260208201905092915050565b7f4661696c656420746f2073656e64206e617469766520746f6b656e0000000000600082015250565b6000610506601b836104bf565b9150610511826104d0565b602082019050919050565b60006020820190508181036000830152610535816104f9565b9050919050565b600061054782610262565b9050919050565b6105578161053c565b82525050565b610566816102c0565b82525050565b600081519050919050565b60005b8381101561059557808201518184015260208101905061057a565b60008484015250505050565b60006105ac8261056c565b6105b681856104bf565b93506105c6818560208601610577565b6105cf81610300565b840191505092915050565b60006060820190506105ef600083018661054e565b6105fc602083018561055d565b818103604083015261060e81846105a1565b9050949350505050565b600081519050919050565b600081905092915050565b600061063982610618565b6106438185610623565b9350610653818560208601610577565b80840191505092915050565b600061066b828461062e565b915081905092915050565b600081905092915050565b7f4661696c656420746f2063616c6c20707265636f6d70696c652062616e6b536560008201527f6e64000000000000000000000000000000000000000000000000000000000000602082015250565b60006106dd602283610676565b91506106e882610681565b602282019050919050565b60006106fe826106d0565b9150819050919050565b6000602082019050818103600083015261072281846105a1565b90509291505056fea2646970667358221220bd148fba67bf9e1966835ecfba5be560625fcf8c88f7890050149168488a782364736f6c63430008180033", - "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a4de557414610030575b600080fd5b61004a6004803603810190610045919061043c565b61004c565b005b60008473ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f193505050509050806100c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bc9061051c565b60405180910390fd5b600061080073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168486604051602401610115939291906105da565b6040516020818303038152906040527f03003bc5000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161019f919061065f565b6000604051808303816000865af19150503d80600081146101dc576040519150601f19603f3d011682016040523d82523d6000602084013e6101e1565b606091505b50509050806040516020016101f5906106f3565b60405160208183030381529060405290610245576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161023c9190610708565b60405180910390fd5b50505050505050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061028d82610262565b9050919050565b61029d81610282565b81146102a857600080fd5b50565b6000813590506102ba81610294565b92915050565b6000819050919050565b6102d3816102c0565b81146102de57600080fd5b50565b6000813590506102f0816102ca565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61034982610300565b810181811067ffffffffffffffff8211171561036857610367610311565b5b80604052505050565b600061037b61024e565b90506103878282610340565b919050565b600067ffffffffffffffff8211156103a7576103a6610311565b5b6103b082610300565b9050602081019050919050565b82818337600083830152505050565b60006103df6103da8461038c565b610371565b9050828152602081018484840111156103fb576103fa6102fb565b5b6104068482856103bd565b509392505050565b600082601f830112610423576104226102f6565b5b81356104338482602086016103cc565b91505092915050565b6000806000806080858703121561045657610455610258565b5b6000610464878288016102ab565b9450506020610475878288016102e1565b935050604085013567ffffffffffffffff8111156104965761049561025d565b5b6104a28782880161040e565b92505060606104b3878288016102e1565b91505092959194509250565b600082825260208201905092915050565b7f4661696c656420746f2073656e64206e617469766520746f6b656e0000000000600082015250565b6000610506601b836104bf565b9150610511826104d0565b602082019050919050565b60006020820190508181036000830152610535816104f9565b9050919050565b600061054782610262565b9050919050565b6105578161053c565b82525050565b610566816102c0565b82525050565b600081519050919050565b60005b8381101561059557808201518184015260208101905061057a565b60008484015250505050565b60006105ac8261056c565b6105b681856104bf565b93506105c6818560208601610577565b6105cf81610300565b840191505092915050565b60006060820190506105ef600083018661054e565b6105fc602083018561055d565b818103604083015261060e81846105a1565b9050949350505050565b600081519050919050565b600081905092915050565b600061063982610618565b6106438185610623565b9350610653818560208601610577565b80840191505092915050565b600061066b828461062e565b915081905092915050565b600081905092915050565b7f4661696c656420746f2063616c6c20707265636f6d70696c652062616e6b536560008201527f6e64000000000000000000000000000000000000000000000000000000000000602082015250565b60006106dd602283610676565b91506106e882610681565b602282019050919050565b60006106fe826106d0565b9150819050919050565b6000602082019050818103600083015261072281846105a1565b90509291505056fea2646970667358221220bd148fba67bf9e1966835ecfba5be560625fcf8c88f7890050149168488a782364736f6c63430008180033", + "bytecode": "0x608060405234801561001057600080fd5b50604051610afc380380610afc833981810160405281019061003291906100db565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610108565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100a88261007d565b9050919050565b6100b88161009d565b81146100c357600080fd5b50565b6000815190506100d5816100af565b92915050565b6000602082840312156100f1576100f0610078565b5b60006100ff848285016100c6565b91505092915050565b6109e5806101176000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a4de557414610030575b600080fd5b61004a600480360381019061004591906105f9565b61004c565b005b60008473ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f193505050509050806100c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bc906106d9565b60405180910390fd5b600061080073ffffffffffffffffffffffffffffffffffffffff166303003bc560008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685876040518463ffffffff1660e01b815260040161012693929190610797565b6020604051808303816000875af1158015610145573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016991906107ea565b9050828114610177826101ea565b610180856101ea565b604051602001610191929190610911565b604051602081830303815290604052906101e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101d8919061095e565b60405180910390fd5b50505050505050565b6060600060016101f9846102b8565b01905060008167ffffffffffffffff811115610218576102176104ce565b5b6040519080825280601f01601f19166020018201604052801561024a5781602001600182028036833780820191505090505b509050600082602001820190505b6001156102ad578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816102a1576102a0610980565b5b04945060008503610258575b819350505050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310610316577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161030c5761030b610980565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310610353576d04ee2d6d415b85acef8100000000838161034957610348610980565b5b0492506020810190505b662386f26fc10000831061038257662386f26fc10000838161037857610377610980565b5b0492506010810190505b6305f5e10083106103ab576305f5e10083816103a1576103a0610980565b5b0492506008810190505b61271083106103d05761271083816103c6576103c5610980565b5b0492506004810190505b606483106103f357606483816103e9576103e8610980565b5b0492506002810190505b600a8310610402576001810190505b80915050919050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061044a8261041f565b9050919050565b61045a8161043f565b811461046557600080fd5b50565b60008135905061047781610451565b92915050565b6000819050919050565b6104908161047d565b811461049b57600080fd5b50565b6000813590506104ad81610487565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610506826104bd565b810181811067ffffffffffffffff82111715610525576105246104ce565b5b80604052505050565b600061053861040b565b905061054482826104fd565b919050565b600067ffffffffffffffff821115610564576105636104ce565b5b61056d826104bd565b9050602081019050919050565b82818337600083830152505050565b600061059c61059784610549565b61052e565b9050828152602081018484840111156105b8576105b76104b8565b5b6105c384828561057a565b509392505050565b600082601f8301126105e0576105df6104b3565b5b81356105f0848260208601610589565b91505092915050565b6000806000806080858703121561061357610612610415565b5b600061062187828801610468565b94505060206106328782880161049e565b935050604085013567ffffffffffffffff8111156106535761065261041a565b5b61065f878288016105cb565b92505060606106708782880161049e565b91505092959194509250565b600082825260208201905092915050565b7f4661696c656420746f2073656e64206e617469766520746f6b656e0000000000600082015250565b60006106c3601b8361067c565b91506106ce8261068d565b602082019050919050565b600060208201905081810360008301526106f2816106b6565b9050919050565b60006107048261041f565b9050919050565b610714816106f9565b82525050565b6107238161047d565b82525050565b600081519050919050565b60005b83811015610752578082015181840152602081019050610737565b60008484015250505050565b600061076982610729565b610773818561067c565b9350610783818560208601610734565b61078c816104bd565b840191505092915050565b60006060820190506107ac600083018661070b565b6107b9602083018561071a565b81810360408301526107cb818461075e565b9050949350505050565b6000815190506107e481610487565b92915050565b600060208284031215610800576107ff610415565b5b600061080e848285016107d5565b91505092915050565b600081905092915050565b7f4946756e546f6b656e2e62616e6b53656e64207375636365656465642062757460008201527f207472616e73666572726564207468652077726f6e6720616d6f756e74000000602082015250565b600061087e603d83610817565b915061088982610822565b603d82019050919050565b7f73656e74416d6f756e7420000000000000000000000000000000000000000000815250565b60006108c582610729565b6108cf8185610817565b93506108df818560208601610734565b80840191505092915050565b7f6578706563746564200000000000000000000000000000000000000000000000815250565b600061091c82610871565b915061092782610894565b600b8201915061093782856108ba565b9150610942826108eb565b60098201915061095282846108ba565b91508190509392505050565b60006020820190508181036000830152610978818461075e565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea2646970667358221220df7092cb424bd549df3b9d958db66a63c029a1e42d78f468fb93c7574ccea23864736f6c63430008180033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c8063a4de557414610030575b600080fd5b61004a600480360381019061004591906105f9565b61004c565b005b60008473ffffffffffffffffffffffffffffffffffffffff166108fc859081150290604051600060405180830381858888f193505050509050806100c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bc906106d9565b60405180910390fd5b600061080073ffffffffffffffffffffffffffffffffffffffff166303003bc560008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685876040518463ffffffff1660e01b815260040161012693929190610797565b6020604051808303816000875af1158015610145573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016991906107ea565b9050828114610177826101ea565b610180856101ea565b604051602001610191929190610911565b604051602081830303815290604052906101e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101d8919061095e565b60405180910390fd5b50505050505050565b6060600060016101f9846102b8565b01905060008167ffffffffffffffff811115610218576102176104ce565b5b6040519080825280601f01601f19166020018201604052801561024a5781602001600182028036833780820191505090505b509050600082602001820190505b6001156102ad578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816102a1576102a0610980565b5b04945060008503610258575b819350505050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310610316577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161030c5761030b610980565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310610353576d04ee2d6d415b85acef8100000000838161034957610348610980565b5b0492506020810190505b662386f26fc10000831061038257662386f26fc10000838161037857610377610980565b5b0492506010810190505b6305f5e10083106103ab576305f5e10083816103a1576103a0610980565b5b0492506008810190505b61271083106103d05761271083816103c6576103c5610980565b5b0492506004810190505b606483106103f357606483816103e9576103e8610980565b5b0492506002810190505b600a8310610402576001810190505b80915050919050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061044a8261041f565b9050919050565b61045a8161043f565b811461046557600080fd5b50565b60008135905061047781610451565b92915050565b6000819050919050565b6104908161047d565b811461049b57600080fd5b50565b6000813590506104ad81610487565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b610506826104bd565b810181811067ffffffffffffffff82111715610525576105246104ce565b5b80604052505050565b600061053861040b565b905061054482826104fd565b919050565b600067ffffffffffffffff821115610564576105636104ce565b5b61056d826104bd565b9050602081019050919050565b82818337600083830152505050565b600061059c61059784610549565b61052e565b9050828152602081018484840111156105b8576105b76104b8565b5b6105c384828561057a565b509392505050565b600082601f8301126105e0576105df6104b3565b5b81356105f0848260208601610589565b91505092915050565b6000806000806080858703121561061357610612610415565b5b600061062187828801610468565b94505060206106328782880161049e565b935050604085013567ffffffffffffffff8111156106535761065261041a565b5b61065f878288016105cb565b92505060606106708782880161049e565b91505092959194509250565b600082825260208201905092915050565b7f4661696c656420746f2073656e64206e617469766520746f6b656e0000000000600082015250565b60006106c3601b8361067c565b91506106ce8261068d565b602082019050919050565b600060208201905081810360008301526106f2816106b6565b9050919050565b60006107048261041f565b9050919050565b610714816106f9565b82525050565b6107238161047d565b82525050565b600081519050919050565b60005b83811015610752578082015181840152602081019050610737565b60008484015250505050565b600061076982610729565b610773818561067c565b9350610783818560208601610734565b61078c816104bd565b840191505092915050565b60006060820190506107ac600083018661070b565b6107b9602083018561071a565b81810360408301526107cb818461075e565b9050949350505050565b6000815190506107e481610487565b92915050565b600060208284031215610800576107ff610415565b5b600061080e848285016107d5565b91505092915050565b600081905092915050565b7f4946756e546f6b656e2e62616e6b53656e64207375636365656465642062757460008201527f207472616e73666572726564207468652077726f6e6720616d6f756e74000000602082015250565b600061087e603d83610817565b915061088982610822565b603d82019050919050565b7f73656e74416d6f756e7420000000000000000000000000000000000000000000815250565b60006108c582610729565b6108cf8185610817565b93506108df818560208601610734565b80840191505092915050565b7f6578706563746564200000000000000000000000000000000000000000000000815250565b600061091c82610871565b915061092782610894565b600b8201915061093782856108ba565b9150610942826108eb565b60098201915061095282846108ba565b91508190509392505050565b60006020820190508181036000830152610978818461075e565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea2646970667358221220df7092cb424bd549df3b9d958db66a63c029a1e42d78f468fb93c7574ccea23864736f6c63430008180033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/x/evm/embeds/contracts/TestNativeSendThenPrecompileSend.sol b/x/evm/embeds/contracts/TestNativeSendThenPrecompileSend.sol index da9cb471b..45ec757b9 100644 --- a/x/evm/embeds/contracts/TestNativeSendThenPrecompileSend.sol +++ b/x/evm/embeds/contracts/TestNativeSendThenPrecompileSend.sol @@ -20,15 +20,20 @@ contract TestNativeSendThenPrecompileSend { bool isSent = nativeRecipient.send(nativeAmount); require(isSent, "Failed to send native token"); - (bool success, ) = FUNTOKEN_PRECOMPILE_ADDRESS.call( - abi.encodeWithSignature( - "bankSend(address,uint256,string)", - erc20, - precompileAmount, - precompileRecipient + uint256 sentAmount = FUNTOKEN_PRECOMPILE.bankSend( + erc20, + precompileAmount, + precompileRecipient + ); + require( + sentAmount == precompileAmount, + string.concat( + "IFunToken.bankSend succeeded but transferred the wrong amount", + "sentAmount ", + Strings.toString(sentAmount), + "expected ", + Strings.toString(precompileAmount) ) ); - - require(success, string.concat("Failed to call precompile bankSend")); } } diff --git a/x/evm/evmtest/erc20.go b/x/evm/evmtest/erc20.go index d8798f71d..176861192 100644 --- a/x/evm/evmtest/erc20.go +++ b/x/evm/evmtest/erc20.go @@ -105,3 +105,19 @@ func BigPow(amount *big.Int, pow10Exp uint8) (powAmount *big.Int) { pow10 := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(pow10Exp)), nil) return new(big.Int).Mul(amount, pow10) } + +type FunTokenBalanceAssert struct { + FunToken evm.FunToken + Account gethcommon.Address + BalanceBank *big.Int + BalanceERC20 *big.Int +} + +func (bals FunTokenBalanceAssert) Assert(t *testing.T, deps TestDeps) { + AssertERC20BalanceEqual( + t, deps, bals.FunToken.Erc20Addr.Address, bals.Account, bals.BalanceERC20, + ) + AssertBankBalanceEqual( + t, deps, bals.FunToken.BankDenom, bals.Account, bals.BalanceBank, + ) +} diff --git a/x/evm/keeper/bank_extension.go b/x/evm/keeper/bank_extension.go index ed9ae45ba..79bafa8b3 100644 --- a/x/evm/keeper/bank_extension.go +++ b/x/evm/keeper/bank_extension.go @@ -17,14 +17,24 @@ var ( type NibiruBankKeeper struct { bankkeeper.BaseKeeper - StateDB *statedb.StateDB + StateDB *statedb.StateDB + TxStateDB *statedb.StateDB } func (evmKeeper *Keeper) NewStateDB( ctx sdk.Context, txConfig statedb.TxConfig, ) *statedb.StateDB { stateDB := statedb.New(ctx, evmKeeper, txConfig) - evmKeeper.Bank.ResetStateDB(stateDB) + evmKeeper.Bank.StateDB = stateDB + return stateDB +} + +func (evmKeeper *Keeper) NewTxStateDB( + ctx sdk.Context, txConfig statedb.TxConfig, +) *statedb.StateDB { + stateDB := statedb.New(ctx, evmKeeper, txConfig) + evmKeeper.Bank.StateDB = stateDB + evmKeeper.Bank.TxStateDB = stateDB return stateDB } @@ -44,17 +54,6 @@ func (bk NibiruBankKeeper) MintCoins( return nil } -func (bk *NibiruBankKeeper) ResetStateDB(db *statedb.StateDB) { - bk.StateDB = db -} - -// s.Require().Equal( -// statedb.FromVM(evmObj).GetBalance( -// eth.NibiruAddrToEthAddr(randomAcc), -// ).String(), -// "420"+strings.Repeat("0", 12), -// ) - func (bk NibiruBankKeeper) BurnCoins( ctx sdk.Context, moduleName string, diff --git a/x/evm/keeper/erc20.go b/x/evm/keeper/erc20.go index 06d2e5ab3..79c189f1e 100644 --- a/x/evm/keeper/erc20.go +++ b/x/evm/keeper/erc20.go @@ -180,7 +180,9 @@ func (k Keeper) CallContract( if err != nil { return nil, fmt.Errorf("failed to pack ABI args: %w", err) } - evmResp, _, err = k.CallContractWithInput(ctx, fromAcc, contract, commit, contractInput) + evmResp, _, err = k.CallContractWithInput( + ctx, fromAcc, contract, commit, contractInput, + ) return evmResp, err } diff --git a/x/evm/keeper/funtoken_from_coin_test.go b/x/evm/keeper/funtoken_from_coin_test.go index b252affe0..f69143772 100644 --- a/x/evm/keeper/funtoken_from_coin_test.go +++ b/x/evm/keeper/funtoken_from_coin_test.go @@ -172,7 +172,7 @@ func (s *FunTokenFromCoinSuite) TestConvertCoinToEvmAndBack() { bankDenom := evm.EVMBankDenom // Initial setup - funTokenErc20Addr := s.fundAndCreateFunToken(deps, 100) + funToken := s.fundAndCreateFunToken(deps, 100) s.T().Log("Convert bank coin to erc-20") _, err := deps.EvmKeeper.ConvertCoinToEvm( @@ -193,7 +193,7 @@ func (s *FunTokenFromCoinSuite) TestConvertCoinToEvmAndBack() { deps.Ctx, &evm.EventConvertCoinToEvm{ Sender: deps.Sender.NibiruAddr.String(), - Erc20ContractAddress: funTokenErc20Addr.String(), + Erc20ContractAddress: funToken.Erc20Addr.String(), ToEthAddr: alice.EthAddr.String(), BankCoin: sdk.NewCoin(bankDenom, sdk.NewInt(10)), }, @@ -208,7 +208,7 @@ func (s *FunTokenFromCoinSuite) TestConvertCoinToEvmAndBack() { s.Require().Equal(sdk.NewInt(90), senderBalance.Amount) // Check 3: erc-20 balance - balance, err := deps.EvmKeeper.ERC20().BalanceOf(funTokenErc20Addr.Address, alice.EthAddr, deps.Ctx) + balance, err := deps.EvmKeeper.ERC20().BalanceOf(funToken.Erc20Addr.Address, alice.EthAddr, deps.Ctx) s.Require().NoError(err) s.Require().Zero(balance.Cmp(big.NewInt(10))) @@ -233,7 +233,7 @@ func (s *FunTokenFromCoinSuite) TestConvertCoinToEvmAndBack() { &precompile.PrecompileAddr_FunToken, true, "bankSend", - funTokenErc20Addr.Address, + funToken.Erc20Addr.Address, big.NewInt(10), deps.Sender.NibiruAddr.String(), ) @@ -248,7 +248,7 @@ func (s *FunTokenFromCoinSuite) TestConvertCoinToEvmAndBack() { s.Require().Equal(sdk.NewInt(100), senderBalance.Amount) // Check 3: erc-20 balance - balance, err = deps.EvmKeeper.ERC20().BalanceOf(funTokenErc20Addr.Address, alice.EthAddr, deps.Ctx) + balance, err = deps.EvmKeeper.ERC20().BalanceOf(funToken.Erc20Addr.Address, alice.EthAddr, deps.Ctx) s.Require().NoError(err) s.Require().Equal("0", balance.String()) @@ -260,7 +260,7 @@ func (s *FunTokenFromCoinSuite) TestConvertCoinToEvmAndBack() { &precompile.PrecompileAddr_FunToken, true, "bankSend", - funTokenErc20Addr.Address, + funToken.Erc20Addr.Address, big.NewInt(10), deps.Sender.NibiruAddr.String(), ) @@ -286,13 +286,14 @@ func (s *FunTokenFromCoinSuite) TestNativeSendThenPrecompileSend() { bankDenom := evm.EVMBankDenom // Initial setup - funTokenErc20Addr := s.fundAndCreateFunToken(deps, 10e6) + sendAmt := big.NewInt(10) + funtoken := s.fundAndCreateFunToken(deps, sendAmt.Int64()) s.T().Log("Deploy Test Contract") deployResp, err := evmtest.DeployContract( &deps, embeds.SmartContract_TestNativeSendThenPrecompileSendJson, - funTokenErc20Addr.Address, + funtoken.Erc20Addr.Address, ) s.Require().NoError(err) @@ -304,7 +305,13 @@ func (s *FunTokenFromCoinSuite) TestNativeSendThenPrecompileSend() { deps.App.BankKeeper, deps.Ctx, testContractNibiAddr, - sdk.NewCoins(sdk.NewCoin(bankDenom, sdk.NewInt(10e6)))), + sdk.NewCoins(sdk.NewCoin(bankDenom, sdk.NewIntFromBigInt(sendAmt)))), + ) + evmtest.AssertBankBalanceEqual( + s.T(), deps, bankDenom, testContractAddr, sendAmt, + ) + evmtest.AssertBankBalanceEqual( + s.T(), deps, bankDenom, evm.EVM_MODULE_ADDRESS, big.NewInt(0), ) s.T().Log("Convert bank coin to erc-20: give test contract 10 WNIBI (erc20)") @@ -312,18 +319,36 @@ func (s *FunTokenFromCoinSuite) TestNativeSendThenPrecompileSend() { sdk.WrapSDKContext(deps.Ctx), &evm.MsgConvertCoinToEvm{ Sender: deps.Sender.NibiruAddr.String(), - BankCoin: sdk.NewCoin(bankDenom, sdk.NewInt(10e6)), + BankCoin: sdk.NewCoin(bankDenom, sdk.NewIntFromBigInt(sendAmt)), ToEthAddr: eth.EIP55Addr{Address: testContractAddr}, }, ) s.Require().NoError(err) + evmtest.FunTokenBalanceAssert{ + FunToken: funtoken, + Account: testContractAddr, + BalanceBank: sendAmt, + BalanceERC20: sendAmt, + }.Assert(s.T(), deps) + evmtest.FunTokenBalanceAssert{ + FunToken: funtoken, + Account: evm.EVM_MODULE_ADDRESS, + BalanceBank: sendAmt, + BalanceERC20: big.NewInt(0), + }.Assert(s.T(), deps) // Alice hex and Alice bech32 is the same address in different representation, // so funds are expected to be available in Alice's bank wallet alice := evmtest.NewEthPrivAcc() + evmtest.FunTokenBalanceAssert{ + FunToken: funtoken, + Account: alice.EthAddr, + BalanceBank: big.NewInt(0), + BalanceERC20: big.NewInt(0), + }.Assert(s.T(), deps) s.T().Log("call test contract") - _, err = deps.EvmKeeper.CallContract( + evmResp, err := deps.EvmKeeper.CallContract( deps.Ctx, embeds.SmartContract_TestNativeSendThenPrecompileSendJson.ABI, deps.Sender.EthAddr, @@ -332,34 +357,34 @@ func (s *FunTokenFromCoinSuite) TestNativeSendThenPrecompileSend() { "nativeSendThenPrecompileSend", []any{ alice.EthAddr, - evm.NativeToWei(big.NewInt(10e6)), // for native evm send: 18 decimals + evm.NativeToWei(sendAmt), // native send uses wei units alice.NibiruAddr.String(), - big.NewInt(10e6), // for precompile bankSend: 6 decimals + sendAmt, // amount for precompile bankSend }..., ) s.Require().NoError(err) - - // Check 1: Alice has 20 NIBI in bank - aliceBankBalance := deps.App.BankKeeper.GetBalance(deps.Ctx, alice.NibiruAddr, bankDenom) - s.Require().Equal(sdk.NewInt(20e6), aliceBankBalance.Amount) - - // Check 2: Alice has 0 WNIBI on ERC20 - aliceERC20Balance, err := deps.EvmKeeper.ERC20().BalanceOf(funTokenErc20Addr.Address, alice.EthAddr, deps.Ctx) - s.Require().NoError(err) - s.Require().Zero(big.NewInt(0).Cmp(aliceERC20Balance)) - - // Check 3: test contract has 0 NIBI in bank - testContractBankBalance := deps.App.BankKeeper.GetBalance(deps.Ctx, testContractNibiAddr, bankDenom) - s.Require().Equal(sdk.NewInt(0), testContractBankBalance.Amount) - - // Check 4: test contract has 0 WNIBI on ERC20 - testContractERC20Balance, err := deps.EvmKeeper.ERC20().BalanceOf(funTokenErc20Addr.Address, testContractAddr, deps.Ctx) - s.Require().NoError(err) - s.Require().Zero(big.NewInt(0).Cmp(testContractERC20Balance)) - - // Check 5: module balance has 0 NIBI escrowed - moduleBalance := deps.App.BankKeeper.GetBalance(deps.Ctx, authtypes.NewModuleAddress(evm.ModuleName), bankDenom) - s.Require().Equal(sdk.NewInt(0), moduleBalance.Amount) + s.Empty(evmResp.VmError) + + evmtest.FunTokenBalanceAssert{ + FunToken: funtoken, + Account: alice.EthAddr, + BalanceBank: new(big.Int).Mul(sendAmt, big.NewInt(2)), + BalanceERC20: big.NewInt(0), + }.Assert(s.T(), deps) + + evmtest.FunTokenBalanceAssert{ + FunToken: funtoken, + Account: testContractAddr, + BalanceBank: big.NewInt(0), + BalanceERC20: big.NewInt(0), + }.Assert(s.T(), deps) + + evmtest.FunTokenBalanceAssert{ + FunToken: funtoken, + Account: evm.EVM_MODULE_ADDRESS, + BalanceBank: big.NewInt(0), + BalanceERC20: big.NewInt(0), + }.Assert(s.T(), deps) } // TestERC20TransferThenPrecompileSend @@ -381,13 +406,13 @@ func (s *FunTokenFromCoinSuite) TestERC20TransferThenPrecompileSend() { bankDenom := evm.EVMBankDenom // Initial setup - funTokenErc20Addr := s.fundAndCreateFunToken(deps, 10e6) + funToken := s.fundAndCreateFunToken(deps, 10e6) s.T().Log("Deploy Test Contract") deployResp, err := evmtest.DeployContract( &deps, embeds.SmartContract_TestERC20TransferThenPrecompileSend, - funTokenErc20Addr.Address, + funToken.Erc20Addr.Address, ) s.Require().NoError(err) @@ -427,12 +452,12 @@ func (s *FunTokenFromCoinSuite) TestERC20TransferThenPrecompileSend() { s.Require().Equal(sdk.NewInt(9e6), aliceBankBalance.Amount) // Check 2: Alice has 1 WNIBI on ERC20 - aliceERC20Balance, err := deps.EvmKeeper.ERC20().BalanceOf(funTokenErc20Addr.Address, alice.EthAddr, deps.Ctx) + aliceERC20Balance, err := deps.EvmKeeper.ERC20().BalanceOf(funToken.Erc20Addr.Address, alice.EthAddr, deps.Ctx) s.Require().NoError(err) s.Require().Zero(big.NewInt(1e6).Cmp(aliceERC20Balance)) // Check 3: test contract has 0 WNIBI on ERC20 - testContractERC20Balance, err := deps.EvmKeeper.ERC20().BalanceOf(funTokenErc20Addr.Address, testContractAddr, deps.Ctx) + testContractERC20Balance, err := deps.EvmKeeper.ERC20().BalanceOf(funToken.Erc20Addr.Address, testContractAddr, deps.Ctx) s.Require().NoError(err) s.Require().Zero(big.NewInt(0).Cmp(testContractERC20Balance)) @@ -442,7 +467,7 @@ func (s *FunTokenFromCoinSuite) TestERC20TransferThenPrecompileSend() { } // fundAndCreateFunToken creates initial setup for tests -func (s *FunTokenFromCoinSuite) fundAndCreateFunToken(deps evmtest.TestDeps, unibiAmount int64) eth.EIP55Addr { +func (s *FunTokenFromCoinSuite) fundAndCreateFunToken(deps evmtest.TestDeps, unibiAmount int64) evm.FunToken { bankDenom := evm.EVMBankDenom s.T().Log("Setup: Create a coin in the bank state") @@ -451,12 +476,15 @@ func (s *FunTokenFromCoinSuite) fundAndCreateFunToken(deps evmtest.TestDeps, uni { Denom: bankDenom, Exponent: 0, - Aliases: nil, + }, + { + Denom: "NIBI", + Exponent: 6, }, }, Base: bankDenom, - Display: bankDenom, - Name: bankDenom, + Display: "NIBI", + Name: "NIBI", Symbol: "NIBI", }) @@ -477,7 +505,16 @@ func (s *FunTokenFromCoinSuite) fundAndCreateFunToken(deps evmtest.TestDeps, uni }, ) s.Require().NoError(err) - return createFunTokenResp.FuntokenMapping.Erc20Addr + + erc20Decimals, err := deps.EvmKeeper.LoadERC20Decimals( + deps.Ctx, + embeds.SmartContract_ERC20Minter.ABI, + createFunTokenResp.FuntokenMapping.Erc20Addr.Address, + ) + s.Require().NoError(err) + s.Require().Equal(erc20Decimals, uint8(6)) + + return createFunTokenResp.FuntokenMapping } type FunTokenFromCoinSuite struct { diff --git a/x/evm/keeper/msg_server.go b/x/evm/keeper/msg_server.go index 60660acd1..57f3cc54a 100644 --- a/x/evm/keeper/msg_server.go +++ b/x/evm/keeper/msg_server.go @@ -351,7 +351,6 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context, // The dirty states in `StateDB` is either committed or discarded after return if commit { - fmt.Println("stateDB.Commit in ApplyEvmMsg") if err := stateDB.Commit(); err != nil { return nil, evmObj, fmt.Errorf("failed to commit stateDB: %w", err) } diff --git a/x/evm/keeper/statedb.go b/x/evm/keeper/statedb.go index 209539305..b85a595a5 100644 --- a/x/evm/keeper/statedb.go +++ b/x/evm/keeper/statedb.go @@ -73,7 +73,7 @@ func (k *Keeper) SetAccBalance( ctx sdk.Context, addr gethcommon.Address, amountEvmDenom *big.Int, ) error { addrBech32 := eth.EthAddrToNibiruAddr(addr) - balance := k.Bank.BaseKeeper.GetBalance(ctx, addrBech32, evm.EVMBankDenom).Amount.BigInt() + balance := k.Bank.GetBalance(ctx, addrBech32, evm.EVMBankDenom).Amount.BigInt() delta := new(big.Int).Sub(amountEvmDenom, balance) bk := k.Bank.BaseKeeper diff --git a/x/evm/precompile/funtoken.go b/x/evm/precompile/funtoken.go index 8fb126f96..92b6701ac 100644 --- a/x/evm/precompile/funtoken.go +++ b/x/evm/precompile/funtoken.go @@ -3,18 +3,20 @@ package precompile import ( "fmt" "math/big" - "sync" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + auth "github.com/cosmos/cosmos-sdk/x/auth/types" gethabi "github.com/ethereum/go-ethereum/accounts/abi" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" "github.com/NibiruChain/nibiru/v2/app/keepers" + "github.com/NibiruChain/nibiru/v2/eth" "github.com/NibiruChain/nibiru/v2/x/evm" "github.com/NibiruChain/nibiru/v2/x/evm/embeds" evmkeeper "github.com/NibiruChain/nibiru/v2/x/evm/keeper" + "github.com/NibiruChain/nibiru/v2/x/evm/statedb" ) var _ vm.PrecompiledContract = (*precompileFunToken)(nil) @@ -54,6 +56,7 @@ func (p precompileFunToken) Run( if err != nil { return nil, err } + p.evmKeeper.Bank.StateDB = start.StateDB method := start.Method switch PrecompileMethod(method.Name) { @@ -73,18 +76,14 @@ func (p precompileFunToken) Run( func PrecompileFunToken(keepers keepers.PublicKeepers) vm.PrecompiledContract { return precompileFunToken{ - bankKeeper: keepers.EvmKeeper.Bank, - evmKeeper: keepers.EvmKeeper, + evmKeeper: keepers.EvmKeeper, } } type precompileFunToken struct { - bankKeeper *evmkeeper.NibiruBankKeeper - evmKeeper *evmkeeper.Keeper + evmKeeper *evmkeeper.Keeper } -var executionGuard sync.Mutex - // bankSend: Implements "IFunToken.bankSend" // // The "args" populate the following function signature in Solidity: @@ -106,10 +105,6 @@ func (p precompileFunToken) bankSend( err = e return } - if !executionGuard.TryLock() { - return nil, fmt.Errorf("bankSend is already in progress") - } - defer executionGuard.Unlock() erc20, amount, to, err := p.decomposeBankSendArgs(args) if err != nil { @@ -157,7 +152,9 @@ func (p precompileFunToken) bankSend( return } } else { + p.evmKeeper.Bank.StateDB = start.StateDB err = p.evmKeeper.Bank.MintCoins(ctx, evm.ModuleName, sdk.NewCoins(coinToSend)) + // err = SafeMintCoins(ctx, evm.ModuleName, coinToSend, p.evmKeeper, start.StateDB) if err != nil { return nil, fmt.Errorf("mint failed for module \"%s\" (%s): contract caller %s: %w", evm.ModuleName, evm.EVM_MODULE_ADDRESS.Hex(), caller.Hex(), err, @@ -166,12 +163,21 @@ func (p precompileFunToken) bankSend( } // Transfer the bank coin + p.evmKeeper.Bank.StateDB = start.StateDB err = p.evmKeeper.Bank.SendCoinsFromModuleToAccount( ctx, evm.ModuleName, toAddr, sdk.NewCoins(coinToSend), ) + // err = SafeSendCoinFromModuleToAccount( + // ctx, + // evm.ModuleName, + // toAddr, + // coinToSend, + // p.evmKeeper, + // start.StateDB, + // ) if err != nil { return nil, fmt.Errorf("send failed for module \"%s\" (%s): contract caller %s: %w", evm.ModuleName, evm.EVM_MODULE_ADDRESS.Hex(), caller.Hex(), err, @@ -214,3 +220,55 @@ func (p precompileFunToken) decomposeBankSendArgs(args []any) ( return } +func SafeMintCoins( + ctx sdk.Context, + moduleName string, + amt sdk.Coin, + ek *evmkeeper.Keeper, + db *statedb.StateDB, +) error { + bk := ek.Bank + err := bk.MintCoins(ctx, evm.ModuleName, sdk.NewCoins(amt)) + if err != nil { + return err + } + if amt.Denom == evm.EVMBankDenom { + evmBech32Addr := auth.NewModuleAddress(evm.ModuleName) + balAfter := bk.GetBalance(ctx, evmBech32Addr, amt.Denom).Amount.BigInt() + db.SetBalanceWei( + evm.EVM_MODULE_ADDRESS, + evm.NativeToWei(balAfter), + ) + } + + return nil +} +func SafeSendCoinFromModuleToAccount( + ctx sdk.Context, + senderModule string, + recipientAddr sdk.AccAddress, + amt sdk.Coin, + ek *evmkeeper.Keeper, + db *statedb.StateDB, +) error { + bk := ek.Bank + err := bk.SendCoinsFromModuleToAccount(ctx, senderModule, recipientAddr, sdk.NewCoins(amt)) + if err != nil { + return err + } + if amt.Denom == evm.EVMBankDenom { + evmBech32Addr := auth.NewModuleAddress(evm.ModuleName) + balAfterFrom := bk.GetBalance(ctx, evmBech32Addr, amt.Denom).Amount.BigInt() + db.SetBalanceWei( + evm.EVM_MODULE_ADDRESS, + evm.NativeToWei(balAfterFrom), + ) + + balAfterTo := bk.GetBalance(ctx, recipientAddr, amt.Denom).Amount.BigInt() + db.SetBalanceWei( + eth.NibiruAddrToEthAddr(recipientAddr), + evm.NativeToWei(balAfterTo), + ) + } + return nil +} diff --git a/x/evm/statedb/statedb.go b/x/evm/statedb/statedb.go index a4594770f..a5059c039 100644 --- a/x/evm/statedb/statedb.go +++ b/x/evm/statedb/statedb.go @@ -84,7 +84,6 @@ func FromVM(evmObj *vm.EVM) *StateDB { // New creates a new state from a given trie. func New(ctx sdk.Context, keeper Keeper, txConfig TxConfig) *StateDB { - fmt.Println("statedb.New called") return &StateDB{ keeper: keeper, evmTxCtx: ctx, @@ -485,9 +484,6 @@ func (s *StateDB) Snapshot() int { // RevertToSnapshot reverts all state changes made since the given revision. func (s *StateDB) RevertToSnapshot(revid int) { - fmt.Printf("len(s.validRevisions): %d\n", len(s.validRevisions)) - fmt.Printf("s.validRevisions: %v\n", s.validRevisions) - // Find the snapshot in the stack of valid snapshots. idx := sort.Search(len(s.validRevisions), func(i int) bool { return s.validRevisions[i].id >= revid