Skip to content

Commit

Permalink
Do not modify the original value passed in executeBatch call (#1661)
Browse files Browse the repository at this point in the history
Do not modify the original value passed in execute_batch call
  • Loading branch information
dssei authored May 14, 2024
1 parent 9813872 commit f130cf4
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 4 deletions.
15 changes: 11 additions & 4 deletions precompiles/wasmd/wasmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,13 @@ func (p Precompile) executeBatch(ctx sdk.Context, method *abi.Method, caller com
rerr = errors.New("sum of coin amounts must equal value specified")
return
}
// Copy to avoid modifying the original value
var valueCopy *big.Int
if value != nil {
valueCopy = new(big.Int).Set(value)
} else {
valueCopy = value
}
for i := 0; i < len(executeMsgs); i++ {
executeMsg := ExecuteMsg(executeMsgs[i])

Expand Down Expand Up @@ -335,16 +342,16 @@ func (p Precompile) executeBatch(ctx sdk.Context, method *abi.Method, caller com
return
}
useiAmt := coins.AmountOf(sdk.MustGetBaseDenom())
if value != nil && !useiAmt.IsZero() {
if valueCopy != nil && !useiAmt.IsZero() {
// process coin amount from the value provided
useiAmtAsWei := useiAmt.Mul(state.SdkUseiToSweiMultiplier).BigInt()
coin, err := pcommon.HandlePaymentUsei(ctx, p.evmKeeper.GetSeiAddressOrDefault(ctx, p.address), senderAddr, useiAmtAsWei, p.bankKeeper)
if err != nil {
rerr = err
return
}
value.Sub(value, useiAmtAsWei)
if value.Sign() == -1 {
valueCopy.Sub(valueCopy, useiAmtAsWei)
if valueCopy.Sign() == -1 {
rerr = errors.New("insufficient value provided for payment")
return
}
Expand Down Expand Up @@ -373,7 +380,7 @@ func (p Precompile) executeBatch(ctx sdk.Context, method *abi.Method, caller com
}
responses = append(responses, res)
}
if value != nil && value.Sign() != 0 {
if valueCopy != nil && valueCopy.Sign() != 0 {
rerr = errors.New("value remaining after execution, must match provided amounts exactly")
return
}
Expand Down
45 changes: 45 additions & 0 deletions precompiles/wasmd/wasmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,51 @@ func TestExecuteBatchOneMessage(t *testing.T) {
require.Equal(t, uint64(0), g)
}

func TestExecuteBatchValueImmutability(t *testing.T) {
testApp := app.Setup(false, false)
mockAddr, mockEVMAddr := testkeeper.MockAddressPair()
ctx := testApp.GetContextForDeliverTx([]byte{}).WithBlockTime(time.Now())
ctx = ctx.WithIsEVM(true)
testApp.EvmKeeper.SetAddressMapping(ctx, mockAddr, mockEVMAddr)
wasmKeeper := wasmkeeper.NewDefaultPermissionKeeper(testApp.WasmKeeper)
p, err := wasmd.NewPrecompile(&testApp.EvmKeeper, wasmKeeper, testApp.WasmKeeper, testApp.BankKeeper)
require.Nil(t, err)
code, err := os.ReadFile("../../example/cosmwasm/echo/artifacts/echo.wasm")
require.Nil(t, err)
codeID, err := wasmKeeper.Create(ctx, mockAddr, code, nil)
require.Nil(t, err)
contractAddr, _, err := wasmKeeper.Instantiate(ctx, codeID, mockAddr, mockAddr, []byte("{}"), "test", sdk.NewCoins())
require.Nil(t, err)

amts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(1000)))
testApp.BankKeeper.MintCoins(ctx, "evm", amts)
testApp.BankKeeper.SendCoinsFromModuleToAccount(ctx, "evm", mockAddr, amts)
testApp.BankKeeper.MintCoins(ctx, "evm", amts)
testApp.BankKeeper.SendCoinsFromModuleToAccount(ctx, "evm", mockAddr, amts)
amtsbz, err := amts.MarshalJSON()
require.Nil(t, err)
executeMethod, err := p.ABI.MethodById(p.ExecuteBatchID)
require.Nil(t, err)
executeMsg := wasmd.ExecuteMsg{
ContractAddress: contractAddr.String(),
Msg: []byte("{\"echo\":{\"message\":\"test msg\"}}"),
Coins: amtsbz,
}
args, err := executeMethod.Inputs.Pack([]wasmd.ExecuteMsg{executeMsg})
require.Nil(t, err)
statedb := state.NewDBImpl(ctx, &testApp.EvmKeeper, true)
evm := vm.EVM{
StateDB: statedb,
}
suppliedGas := uint64(1000000)
testApp.BankKeeper.SendCoins(ctx, mockAddr, testApp.EvmKeeper.GetSeiAddressOrDefault(ctx, common.HexToAddress(wasmd.WasmdAddress)), amts)
value := big.NewInt(1000_000_000_000_000)
valueCopy := new(big.Int).Set(value)
p.RunAndCalculateGas(&evm, mockEVMAddr, mockEVMAddr, append(p.ExecuteBatchID, args...), suppliedGas, value, nil, false)

require.Equal(t, valueCopy, value)
}

func TestExecuteBatchMultipleMessages(t *testing.T) {
testApp := app.Setup(false, false)
mockAddr, mockEVMAddr := testkeeper.MockAddressPair()
Expand Down

0 comments on commit f130cf4

Please sign in to comment.