Skip to content

Commit

Permalink
test(evm): precompile call with revert
Browse files Browse the repository at this point in the history
  • Loading branch information
onikonychev committed Nov 4, 2024
1 parent 528f51a commit 0f3d3fa
Show file tree
Hide file tree
Showing 4 changed files with 284 additions and 12 deletions.
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
);

require(
sentAmount == precompileAmount,
string.concat(
"IFunToken.bankSend succeeded but transferred the wrong amount",
"sentAmount ",
Strings.toString(nativeAmount),
"expected ",
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

0 comments on commit 0f3d3fa

Please sign in to comment.