Solidity Internal exception in StandardCompiler - ethereum

This is the source code
pragma solidity ^0.5.1;
contract myContract{
string value;
constructor() public {
value = "myValue";
}
function get() public view returns(string memory){
return value;
}
function set(string memory _value) public{
value = _value;
}
}
Selected Compiler on Remix IDE is 0.5.1+commit.c8a2cb62
Selected Environment is Javascript VM
When I compile the command I get this error
Internal exception in StandardCompiler::compileInternal: /root/project/libevmasm/ExpressionClasses.cpp(187): Throw in function ExpressionClasses::Id dev::eth::ExpressionClasses::tryToSimplify(const dev::eth::ExpressionClasses::Expression &)
Dynamic exception type: boost::exception_detail::clone_impl<dev::eth::OptimizerException>
std::exception::what: Rule list not properly initialized.
[dev::tag_comment*] = Rule list not properly initial
However this error does not pop up for same source code if I select the compiler as 0.5.11
Other users are saying that they are getting this error on pre 0.5.3 compilers.

This is a bug in a certain version of the compiler - it does not work properly if the javascript runtime environment does not provide enough stack space or memory. It should work with the most recent compilers.
Check this thread for more info

Related

factory contract reverts

I am trying to create a factory contract, which I call DAG:
pragma solidity >=0.7.0 <0.9.0;
import "./Agent.sol";
contract DAG {
address[] agents;
function createDAG() public returns (address) {
// create root agent
address[] memory parentsOfRoot;
address rootAddress = createAgent(parentsOfRoot);
// create child
address[] memory parentsOfChild;
parentsOfChild[0] = rootAddress;
createAgent(parentsOfChild);
return rootAddress;
}
function createAgent(address[] memory _parents) public returns(address) {
Agent agent = new Agent(_parents);
agents[agents.length - 1] = address(agent);
return address(agent);
}
}
It is meant to make something like a connected list of Agents.
pragma solidity >=0.7.0 <0.9.0;
contract Agent {
address[] parents;
constructor(
address[] memory _parents
){
parents = _parents;
}
function getParents() public view returns (address[] memory) {
return parents;
}
}
For some reason, when I call createDAG in the RemixIDE, I get the following error:
transact to DAG.createDAG pending ... transact to DAG.createDAG
errored: VM error: revert.
revert The transaction has been reverted to the initial state. Note:
The called function should be payable if you send value and the value
you send should be less than your current balance. Debug the
transaction to get more information.
Can anyone help me understand why I am unable to call createDAG?
Your snippet is trying to assign into 0th index of the array but this index doesn't exist at that moment. Which throws an "out of bounds" exception.
address[] memory parentsOfChild; // 0 items
parentsOfChild[0] = rootAddress; // trying to assign the first item (index 0)
It's currently (v0.8) not possible to resize in-memory arrays, so you'll need to initialize the array with an already predefined length.
address[] memory parentsOfChild = new address[](1); // 1 empty item
parentsOfChild[0] = rootAddress;
Then you're going to run into another logical error. Function createAgent() is also trying to assign a value to an "out of bounds" index.
When the agents array is empty, this snippet is trying to assign into index -1.
agents[agents.length - 1] = address(agent);
If you want to add a new item to the agents array, you can use the .push() member function of the array.
// instead of `agents[agents.length - 1] = address(agent);`
agents.push(address(agent));

Revert throws "missing revert data" in inherited method

I've got a base contract which I use to add functionality to other contracts by inheritance.
For some reason, neither revert nor require are working as expected when the method is called by a descendent which acquires the method via "is". eg contract Sample is AttribChecker
Here's part of the method in Attribchecker;
function getAttribute(string memory attribName) public virtual view returns(string memory) {
BindingCollection coll = BindingCollection(_bindingCollectionAddr);
bool attrExists = coll.existsAttrib(attribName);
console.log("attr exists?", attrExists); //works as expected
if (!attrExists) revert("no such attrib"); //when attrExists is true, fails here
[...]
}
Instead of getting a normal revert message, I get this error:
Error: missing revert data in call exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (error={"stackTrace":[{"type":4,"sourceReference":{"function":"getAttribute","contract":"SampleContract","sourceName":"contracts/Embeddable.sol","sourceContent":"//SPDX-License-Identifier: Unlicense\npragma solidity ^0.8.0;\n\nimport \"./BKLibrary.sol\";\nimport \"./BindingCollection.sol\";\nimport \"hardhat/console.sol\";\n\ncontract Embeddable {\n using BKLibrary for string;\n \n bool private _published;\n string private _fqBinding;\n address private _bindingCollectionAddr;\n address private owner;\n\n modifier onlyOwner {\n require(msg.sender==owner, \"onlyOwner\");\n _;\n }\n\n constructor(address bindingColAddress_) (more...)
I would like it to fail with the normal revert message so I can see that it failed because of "no such attrib" not all this other stuff.
Why is it failing with "missing revert data" on the call to revert?
require takes a boolean, like so:
require(condition, error message);
So your check should look like this:
require(attrExists, "no such attrib");
But your problem is probably with the coll.existsAttrib. From the stack trace, it appears that the revert is caused by an external call. The only external call here is the coll.existsAttrib.

Warning: Function state mutability can be restricted to pure function

I am new to solidity and I have been trying to print out simple messages using functions in solidity, but I have failed to deploy successfully, and there is an error that I can not figure out what's wrong.
This is what I have tried so far:
pragma solidity ^0.6.0;
contract test {
string public _feedback;
function reply(string memory feedback) public
{
feedback = "Well done!";
}
}
The error I am receiving is "Warning: Function state mutability can be restricted to pure function"
The compiler simply WARNS that the result of the execution of the function reply is fixed and "canonically" this can be indicated by adding a pure specifier to it:
function reply(string memory feedback) public pure
{
feedback = "Well done!";
}
But even without this change, the contract will be compiled and created correctly. Only in its current form, you will not be able to understand in any way what it is working out :-)

How to fix "Gas estimation failed error" when transferring Minter and Owner roles to a new account in one function?

I have a simple ERC20 contract which is ERC20Detailed, ERC20Mintable and Ownable. On deployment I want:
Add Minter to a new account, passed in the argument
Remove deployer from Minter role
Transfer Ownership to a new account, passed in the argument
Same actions I have declared in another function called transferRights()
The problem is that I am getting "Gas estimation failed error", which isn't because I don't have enough gas, but there might be a bug in the code. If I remove first two (addMinter, renounceMinter) actions, then it's all good (No warning).
I have deployed this contract on Ropsten, where I was getting same error in the beginning, but by commenting first two actions and adding them again transaction went through without any warning and Contract works as it supposed to be.
pragma solidity ^0.5.0;
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol";
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/ownership/Ownable.sol";
contract MyToken is ERC20Detailed, ERC20Mintable, Ownable {
uint256 private msgCount;
address constant ETHER = address(0);
mapping(uint256 => string) private message;
constructor(string memory name, string memory symbol, uint8 decimals, address _newOwner) ERC20Detailed(name, symbol, decimals) public {
addMinter(_newOwner);
renounceMinter();
transferOwnership(_newOwner);
}
function doMint(uint256 _amount, address _beneficiary1, address _beneficiary2, address _beneficiary3) public onlyOwner {
require (_amount >= 0);
require(_beneficiary1 != ETHER && _beneficiary2 != ETHER && _beneficiary3 != ETHER);
require(mint(_beneficiary1, _amount.mul(20).div(100)));
require(mint(_beneficiary2, _amount.mul(30).div(100)));
require(mint(_beneficiary3, _amount.mul(50).div(100)));
}
function setMessage(string memory _message) public onlyOwner {
message[msgCount] = _message;
msgCount = msgCount.add(1);
}
function readMessage(uint256 _msgId) public view returns(string memory) {
return message[_msgId];
}
function transferRights(address _newOwner) public onlyOwner {
addMinter(_newOwner);
renounceMinter();
transferOwnership(_newOwner);
}
}
I can still send a transaction and deploy I guess (as mentioned above I did it on testnet), even though it is saying "The transaction execution will likely fail", but I want to make sure that code is bug free. Any feedback would be greatly appreciated. Thanks!
UPDATE
Problem found! In the constructor I was passing the same account address as I was using for deploying. Thus, it resulted adding the Minter role to myself, which I already had.

Ethereum Transaction Error while calling a contract function from another contract

Following smart contract works fine in Remix and Ganache. However doesn't work on private ethereum blockchains like Kaleido or Azure. What am I missing. When I call setA it consumes all gas and then fails.
pragma solidity ^0.4.24;
contract TestA {
uint public someValue;
function setValue(uint a) public returns (bool){
someValue = a;
return true;
}
}
contract TestB {
address public recentA;
function createA() public returns (address) {
recentA = new TestA();
return recentA;
}
function setA() public returns (bool) {
TestA(recentA).setValue(6);
return true;
}
}
I tried your contract in Kaleido, and found even calling eth_estimateGas with very large numbers was resulting in "out of gas".
I changed the setValue cross-contract call to set a gas value, and I was then able to call setA, and estimating the gas for setA showed just 31663.
recentA.setValue.gas(10000)(6);
I suspect this EVM behavior is related to permissioned chains with a gasprice of zero. However, that is speculation as I haven't investigated the internals.
I've also added eth_estimateGas, and support for multiple contracts in a Solidity file, to kaleido-go here in case it's helpful:
https://github.com/kaleido-io/kaleido-go
Another possibility for others encountering "out of gas" calling across contracts - In Geth if a require call fails in a called contract, the error is reported as "out of gas" (rather than "execution reverted", or a detailed reason for the require failing).
You are hitting the limit of gas allowed to be spent per block. Information about gas limit is included into every block, so you can check what's this value is right now in your blockchain. Currently on Ethereum MainNet, GasLimit (per block) is about 8 millions (see here https://etherscan.io/blocks)
To fix this, you can start your blockchain with modified genesis file. Try to increase value of gasLimit parameter in your genesis file, which specifies the maximum amount of gas processed per block. Try "gasLimit": "8000000".
Try to discard the return statement of setValue method in contract TestA.
pragma solidity ^0.4.24;
contract TestA {
uint public someValue;
function setValue(uint a) public {
someValue = a;
}
}