Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(evm): precompile call with revert #2105

Merged
merged 2 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ depend on x/bank, such as the EVM and Wasm modules.
tests for race conditions within funtoken precompile
- [#2100](https://github.com/NibiruChain/nibiru/pull/2100) - refactor: cleanup statedb and precompile sections
- [#2101](https://github.com/NibiruChain/nibiru/pull/2101) - fix(evm): tx receipt proper marshalling
- [#2105](https://github.com/NibiruChain/nibiru/pull/2105) - test(evm): precompile call with revert


#### Nibiru EVM | Before Audit 1 - 2024-10-18
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
{
"_format": "hh-sol-artifact-1",
"contractName": "TestPrecompileSelfCallRevert",
"sourceName": "contracts/TestPrecompileSelfCallRevert.sol",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "erc20_",
"type": "address"
}
],
"stateMutability": "payable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "nativeRecipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "nativeAmount",
"type": "uint256"
},
{
"internalType": "string",
"name": "precompileRecipient",
"type": "string"
},
{
"internalType": "uint256",
"name": "precompileAmount",
"type": "uint256"
}
],
"name": "selfCallTransferFunds",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "nativeRecipient",
"type": "address"
},
{
"internalType": "uint256",
"name": "nativeAmount",
"type": "uint256"
},
{
"internalType": "string",
"name": "precompileRecipient",
"type": "string"
},
{
"internalType": "uint256",
"name": "precompileAmount",
"type": "uint256"
}
],
"name": "transferFunds",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
],
"bytecode": "0x60806040526000600155604051610c8e380380610c8e833981810160405281019061002a91906100d3565b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610100565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100a082610075565b9050919050565b6100b081610095565b81146100bb57600080fd5b50565b6000815190506100cd816100a7565b92915050565b6000602082840312156100e9576100e8610070565b5b60006100f7848285016100be565b91505092915050565b610b7f8061010f6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80636ad4fe961461003b578063705964db14610057575b600080fd5b610055600480360381019061005091906106c1565b610073565b005b610071600480360381019061006c91906106c1565b610208565b005b8373ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f193505050506100e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100de906107a1565b60405180910390fd5b600061080073ffffffffffffffffffffffffffffffffffffffff166303003bc560008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684866040518463ffffffff1660e01b81526004016101489392919061085f565b6020604051808303816000875af1158015610167573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061018b91906108b2565b9050818114610199856102b2565b6101a2846102b2565b6040516020016101b39291906109d9565b60405160208183030381529060405290610203576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101fa9190610a26565b60405180910390fd5b600080fd5b6001600081548092919061021b90610a77565b91905055503073ffffffffffffffffffffffffffffffffffffffff16636ad4fe96858585856040518563ffffffff1660e01b815260040161025f9493929190610ace565b600060405180830381600087803b15801561027957600080fd5b505af192505050801561028a575060015b6102ab57600160008154809291906102a190610a77565b91905055506102ac565b5b50505050565b6060600060016102c184610380565b01905060008167ffffffffffffffff8111156102e0576102df610596565b5b6040519080825280601f01601f1916602001820160405280156103125781602001600182028036833780820191505090505b509050600082602001820190505b600115610375578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161036957610368610b1a565b5b04945060008503610320575b819350505050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106103de577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816103d4576103d3610b1a565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061041b576d04ee2d6d415b85acef8100000000838161041157610410610b1a565b5b0492506020810190505b662386f26fc10000831061044a57662386f26fc1000083816104405761043f610b1a565b5b0492506010810190505b6305f5e1008310610473576305f5e100838161046957610468610b1a565b5b0492506008810190505b612710831061049857612710838161048e5761048d610b1a565b5b0492506004810190505b606483106104bb57606483816104b1576104b0610b1a565b5b0492506002810190505b600a83106104ca576001810190505b80915050919050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610512826104e7565b9050919050565b61052281610507565b811461052d57600080fd5b50565b60008135905061053f81610519565b92915050565b6000819050919050565b61055881610545565b811461056357600080fd5b50565b6000813590506105758161054f565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6105ce82610585565b810181811067ffffffffffffffff821117156105ed576105ec610596565b5b80604052505050565b60006106006104d3565b905061060c82826105c5565b919050565b600067ffffffffffffffff82111561062c5761062b610596565b5b61063582610585565b9050602081019050919050565b82818337600083830152505050565b600061066461065f84610611565b6105f6565b9050828152602081018484840111156106805761067f610580565b5b61068b848285610642565b509392505050565b600082601f8301126106a8576106a761057b565b5b81356106b8848260208601610651565b91505092915050565b600080600080608085870312156106db576106da6104dd565b5b60006106e987828801610530565b94505060206106fa87828801610566565b935050604085013567ffffffffffffffff81111561071b5761071a6104e2565b5b61072787828801610693565b925050606061073887828801610566565b91505092959194509250565b600082825260208201905092915050565b7f455448207472616e73666572206661696c656400000000000000000000000000600082015250565b600061078b601383610744565b915061079682610755565b602082019050919050565b600060208201905081810360008301526107ba8161077e565b9050919050565b60006107cc826104e7565b9050919050565b6107dc816107c1565b82525050565b6107eb81610545565b82525050565b600081519050919050565b60005b8381101561081a5780820151818401526020810190506107ff565b60008484015250505050565b6000610831826107f1565b61083b8185610744565b935061084b8185602086016107fc565b61085481610585565b840191505092915050565b600060608201905061087460008301866107d3565b61088160208301856107e2565b81810360408301526108938184610826565b9050949350505050565b6000815190506108ac8161054f565b92915050565b6000602082840312156108c8576108c76104dd565b5b60006108d68482850161089d565b91505092915050565b600081905092915050565b7f4946756e546f6b656e2e62616e6b53656e64207375636365656465642062757460008201527f207472616e73666572726564207468652077726f6e6720616d6f756e74000000602082015250565b6000610946603d836108df565b9150610951826108ea565b603d82019050919050565b7f73656e74416d6f756e7420000000000000000000000000000000000000000000815250565b600061098d826107f1565b61099781856108df565b93506109a78185602086016107fc565b80840191505092915050565b7f6578706563746564200000000000000000000000000000000000000000000000815250565b60006109e482610939565b91506109ef8261095c565b600b820191506109ff8285610982565b9150610a0a826109b3565b600982019150610a1a8284610982565b91508190509392505050565b60006020820190508181036000830152610a408184610826565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610a8282610545565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610ab457610ab3610a48565b5b600182019050919050565b610ac881610507565b82525050565b6000608082019050610ae36000830187610abf565b610af060208301866107e2565b8181036040830152610b028185610826565b9050610b1160608301846107e2565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea26469706673582212209f94c0998ce7cd55cbc2c6e9d67d15c37043043fd2ad0f792c2c2c8b09b8284764736f6c63430008180033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c80636ad4fe961461003b578063705964db14610057575b600080fd5b610055600480360381019061005091906106c1565b610073565b005b610071600480360381019061006c91906106c1565b610208565b005b8373ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f193505050506100e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100de906107a1565b60405180910390fd5b600061080073ffffffffffffffffffffffffffffffffffffffff166303003bc560008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684866040518463ffffffff1660e01b81526004016101489392919061085f565b6020604051808303816000875af1158015610167573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061018b91906108b2565b9050818114610199856102b2565b6101a2846102b2565b6040516020016101b39291906109d9565b60405160208183030381529060405290610203576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101fa9190610a26565b60405180910390fd5b600080fd5b6001600081548092919061021b90610a77565b91905055503073ffffffffffffffffffffffffffffffffffffffff16636ad4fe96858585856040518563ffffffff1660e01b815260040161025f9493929190610ace565b600060405180830381600087803b15801561027957600080fd5b505af192505050801561028a575060015b6102ab57600160008154809291906102a190610a77565b91905055506102ac565b5b50505050565b6060600060016102c184610380565b01905060008167ffffffffffffffff8111156102e0576102df610596565b5b6040519080825280601f01601f1916602001820160405280156103125781602001600182028036833780820191505090505b509050600082602001820190505b600115610375578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161036957610368610b1a565b5b04945060008503610320575b819350505050919050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106103de577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816103d4576103d3610b1a565b5b0492506040810190505b6d04ee2d6d415b85acef8100000000831061041b576d04ee2d6d415b85acef8100000000838161041157610410610b1a565b5b0492506020810190505b662386f26fc10000831061044a57662386f26fc1000083816104405761043f610b1a565b5b0492506010810190505b6305f5e1008310610473576305f5e100838161046957610468610b1a565b5b0492506008810190505b612710831061049857612710838161048e5761048d610b1a565b5b0492506004810190505b606483106104bb57606483816104b1576104b0610b1a565b5b0492506002810190505b600a83106104ca576001810190505b80915050919050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610512826104e7565b9050919050565b61052281610507565b811461052d57600080fd5b50565b60008135905061053f81610519565b92915050565b6000819050919050565b61055881610545565b811461056357600080fd5b50565b6000813590506105758161054f565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6105ce82610585565b810181811067ffffffffffffffff821117156105ed576105ec610596565b5b80604052505050565b60006106006104d3565b905061060c82826105c5565b919050565b600067ffffffffffffffff82111561062c5761062b610596565b5b61063582610585565b9050602081019050919050565b82818337600083830152505050565b600061066461065f84610611565b6105f6565b9050828152602081018484840111156106805761067f610580565b5b61068b848285610642565b509392505050565b600082601f8301126106a8576106a761057b565b5b81356106b8848260208601610651565b91505092915050565b600080600080608085870312156106db576106da6104dd565b5b60006106e987828801610530565b94505060206106fa87828801610566565b935050604085013567ffffffffffffffff81111561071b5761071a6104e2565b5b61072787828801610693565b925050606061073887828801610566565b91505092959194509250565b600082825260208201905092915050565b7f455448207472616e73666572206661696c656400000000000000000000000000600082015250565b600061078b601383610744565b915061079682610755565b602082019050919050565b600060208201905081810360008301526107ba8161077e565b9050919050565b60006107cc826104e7565b9050919050565b6107dc816107c1565b82525050565b6107eb81610545565b82525050565b600081519050919050565b60005b8381101561081a5780820151818401526020810190506107ff565b60008484015250505050565b6000610831826107f1565b61083b8185610744565b935061084b8185602086016107fc565b61085481610585565b840191505092915050565b600060608201905061087460008301866107d3565b61088160208301856107e2565b81810360408301526108938184610826565b9050949350505050565b6000815190506108ac8161054f565b92915050565b6000602082840312156108c8576108c76104dd565b5b60006108d68482850161089d565b91505092915050565b600081905092915050565b7f4946756e546f6b656e2e62616e6b53656e64207375636365656465642062757460008201527f207472616e73666572726564207468652077726f6e6720616d6f756e74000000602082015250565b6000610946603d836108df565b9150610951826108ea565b603d82019050919050565b7f73656e74416d6f756e7420000000000000000000000000000000000000000000815250565b600061098d826107f1565b61099781856108df565b93506109a78185602086016107fc565b80840191505092915050565b7f6578706563746564200000000000000000000000000000000000000000000000815250565b60006109e482610939565b91506109ef8261095c565b600b820191506109ff8285610982565b9150610a0a826109b3565b600982019150610a1a8284610982565b91508190509392505050565b60006020820190508181036000830152610a408184610826565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000610a8282610545565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610ab457610ab3610a48565b5b600182019050919050565b610ac881610507565b82525050565b6000608082019050610ae36000830187610abf565b610af060208301866107e2565b8181036040830152610b028185610826565b9050610b1160608301846107e2565b95945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea26469706673582212209f94c0998ce7cd55cbc2c6e9d67d15c37043043fd2ad0f792c2c2c8b09b8284764736f6c63430008180033",
"linkReferences": {},
"deployedLinkReferences": {}
}
62 changes: 62 additions & 0 deletions x/evm/embeds/contracts/TestPrecompileSelfCallRevert.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.24;

import "./IFunToken.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

contract TestPrecompileSelfCallRevert {
address erc20;
uint counter = 0;

constructor(address erc20_) payable {
erc20 = erc20_;
}

function selfCallTransferFunds(
address payable nativeRecipient,
uint256 nativeAmount,
string memory precompileRecipient,
uint256 precompileAmount
) external {
counter++;
try
TestPrecompileSelfCallRevert(payable(address(this))).transferFunds(
nativeRecipient,
nativeAmount,
precompileRecipient,
precompileAmount
)
{} catch // [1]
{
counter++;
}
}

function transferFunds(
address payable nativeRecipient,
uint256 nativeAmount,
string memory precompileRecipient,
uint256 precompileAmount
) external {
require(nativeRecipient.send(nativeAmount), "ETH transfer failed"); // wei

uint256 sentAmount = FUNTOKEN_PRECOMPILE.bankSend(
erc20,
precompileAmount, // micro-WNIBI
precompileRecipient
);
Comment on lines +43 to +47
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Undefined identifier: FUNTOKEN_PRECOMPILE

The variable FUNTOKEN_PRECOMPILE is used but not defined in this contract. This will result in a compilation error. Ensure that FUNTOKEN_PRECOMPILE is declared or imported appropriately.

Apply this diff to fix the issue:

+// Define the FUNTOKEN_PRECOMPILE constant at the beginning of the contract
+address constant FUNTOKEN_PRECOMPILE_ADDRESS = /* insert precompile address here */;
+IFunToken constant FUNTOKEN_PRECOMPILE = IFunToken(FUNTOKEN_PRECOMPILE_ADDRESS);

Replace /* insert precompile address here */ with the actual address of the IFunToken precompile contract.

Committable suggestion skipped: line range outside the PR's diff.


require(
sentAmount == precompileAmount,
string.concat(
"IFunToken.bankSend succeeded but transferred the wrong amount",
"sentAmount ",
Strings.toString(nativeAmount),
"expected ",
Strings.toString(precompileAmount)
)
);
Comment on lines +50 to +58
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incorrect variable used in error message

In the error message within the require statement, Strings.toString(nativeAmount) is used instead of Strings.toString(sentAmount). This will display the wrong amount if the check fails.

Apply this diff to correct the error message:

require(
    sentAmount == precompileAmount,
    string.concat(
        "IFunToken.bankSend succeeded but transferred the wrong amount. ",
        "Sent amount: ",
-       Strings.toString(nativeAmount),
+       Strings.toString(sentAmount),
        ", Expected amount: ",
        Strings.toString(precompileAmount)
    )
);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
sentAmount == precompileAmount,
string.concat(
"IFunToken.bankSend succeeded but transferred the wrong amount",
"sentAmount ",
Strings.toString(nativeAmount),
"expected ",
Strings.toString(precompileAmount)
)
);
sentAmount == precompileAmount,
string.concat(
"IFunToken.bankSend succeeded but transferred the wrong amount. ",
"Sent amount: ",
Strings.toString(sentAmount),
", Expected amount: ",
Strings.toString(precompileAmount)
)
);


revert(); // [4]
}
}
13 changes: 13 additions & 0 deletions x/evm/embeds/embeds.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ var (
testERC20TransferThenPrecompileSendJson []byte
//go:embed artifacts/contracts/TestNativeSendThenPrecompileSend.sol/TestNativeSendThenPrecompileSend.json
testNativeSendThenPrecompileSendJson []byte
//go:embed artifacts/contracts/TestPrecompileSelfCallRevert.sol/TestPrecompileSelfCallRevert.json
testPrecompileSelfCallRevertJson []byte
)

var (
Expand Down Expand Up @@ -96,6 +98,16 @@ var (
Name: "TestERC20TransferThenPrecompileSend.sol",
EmbedJSON: testERC20TransferThenPrecompileSendJson,
}

// SmartContract_TestPrecompileSelfCallRevert is a test contract
// that creates another instance of itself, calls the precompile method and then force reverts.
// It tests a race condition where the state DB commit
// may save the wrong state before the precompile execution, not revert it entirely,
// potentially causing an infinite mint of funds.
SmartContract_TestPrecompileSelfCallRevert = CompiledEvmContract{
Name: "TestPrecompileSelfCallRevert.sol",
EmbedJSON: testPrecompileSelfCallRevertJson,
}
)

func init() {
Expand All @@ -108,6 +120,7 @@ func init() {
SmartContract_TestERC20MaliciousTransfer.MustLoad()
SmartContract_TestNativeSendThenPrecompileSendJson.MustLoad()
SmartContract_TestERC20TransferThenPrecompileSend.MustLoad()
SmartContract_TestPrecompileSelfCallRevert.MustLoad()
}

type CompiledEvmContract struct {
Expand Down
Loading
Loading