ParserError when verifying Truffle contract on Etherscan - ethereum

I have a contract which has been deployed to the main Ethereum network, the contract code works and compiles fine when deploying and I can interact with the contract using metamask/MEW.
However, when I go to verify the contract on Etherscan, I get a compilation error.
I am using the beta truffle compiler from etherscan: https://etherscan.io/verifyContract2
I have bunched all of my code together using npm truffle-flattener
I have created the encoded constructor parameters using: https://abi.hashex.org/
I have then used the optimizer in truffle.js with runs = 200:
solc: {
optimizer: {
enabled: true,
runs: 200
}
}
I have then used the compiler version which is set in the JSON file below:
...
...
},
"compiler": {
"name": "solc",
"version": "0.4.21+commit.dfe3193c.Emscripten.clang"
},
"networks": {
"1": {
"events": {},
"links": {
"SaleStagesLib": "0x0ea918c7c1bed2358530baad064d361438543067",
"BytesDeserializer": "0x278cfd9ed99cf90ebe2e1a750b50e5811a81af77"
},
"address": "0x3a2c34ba7be06c7104bb642f4ce74dc4c317f373",
"transactionHash": "0x02e0a895cd3dcf98ee71b9d823d69b5701d6e76bd326757babac1c2bf805ff8d"
}
},
"schemaVersion": "2.0.0",
"updatedAt": "2018-03-31T14:09:25.579Z"
}
The following throws a ParseError in etherscan pointing towards the Ownable contract:
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* #dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
function Ownable() public {
owner = msg.sender;
}
/**
* #dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* #dev Allows the current owner to transfer control of the contract to a newOwner.
* #param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
The error reads:
myc:150:30: ParserError: Expected token Semicolon got 'LParen'
emit OwnershipTransferred(owner, newOwner)
^
However, I'd like to point out that this code compiled correctly with no errors in truffle, and I have successfully interacted with the contract on the mainnet.
Any ideas why the compiler is throwing this error?

I removed the 'emits' causing the ParseError to be thrown and the verification worked. I believe this may be an issue between truffle and etherscans compiler versions.

Related

Getting AAVE smartcontract error - caller is not ownable

I am getting the following error when try to execute the flashloan in Goerli testnet with USDC
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted: Ownable: caller is not the owner
{
"originalError": {
"code": 3,
"data": "0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000204f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572",
"message": "execution reverted: Ownable: caller is not the owner"
}
}
I have used the following addresses for deployment and flashloan
//Goerli testnet 0xC911B590248d127aD18546B186cC6B324e99F02c
//faucet address 0x1ca525Cd5Cb77DB5Fa9cBbA02A0824e283469DBe
//USDC address 0x65aFADD39029741B3b8f0756952C74678c9cEC93
Could you please advice how can i solve this problem?
I am using the following code
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.10;
pragma experimental ABIEncoderV2;
//Deploy address
//Goerli testnet 0xC911B590248d127aD18546B186cC6B324e99F02c
//faucet address 0x1ca525Cd5Cb77DB5Fa9cBbA02A0824e283469DBe
//USDC address 0x65aFADD39029741B3b8f0756952C74678c9cEC93
import {
IPoolAddressesProvider
} from "https://github.com/aave/aave-v3-core/contracts/interfaces/IPoolAddressesProvider.sol";
import { IPool } from "https://github.com/aave/aave-v3-core/contracts/interfaces/IPool.sol";
import { IFlashLoanSimpleReceiver } from "https://github.com/aave/aave-v3-core/contracts/flashloan/interfaces/IFlashLoanSimpleReceiver.sol";
import { IERC20 } from "https://github.com/aave/aave-v3-core/contracts/dependencies/openzeppelin/contracts/IERC20.sol";
import { SafeMath } from "https://github.com/aave/aave-v3-core/contracts/dependencies/openzeppelin/contracts/SafeMath.sol";
interface IFaucet {
function mint(
address _token,
uint256 _amount
) external;
}
abstract contract FlashLoanSimpleReceiverBase is IFlashLoanSimpleReceiver {
using SafeMath for uint256;
IPoolAddressesProvider public immutable override ADDRESSES_PROVIDER;
IPool public immutable override POOL;
IFaucet public immutable FAUCET;
constructor(IPoolAddressesProvider provider, IFaucet faucet) {
ADDRESSES_PROVIDER = provider;
POOL = IPool(provider.getPool());
FAUCET = faucet;
}
}
/**
!!!
Never keep funds permanently on your FlashLoanSimpleReceiverBase contract as they could be
exposed to a 'griefing' attack, where the stored funds are used by an attacker.
!!!
*/
contract MySimpleFlashLoanV3 is FlashLoanSimpleReceiverBase {
using SafeMath for uint256;
constructor(IPoolAddressesProvider _addressProvider, IFaucet _faucet) FlashLoanSimpleReceiverBase(_addressProvider, _faucet) {}
/**
This function is called after your contract has received the flash loaned amount
*/
function executeOperation(
address asset,
uint256 amount,
uint256 premium,
address initiator,
bytes calldata params
)
external
override
returns (bool)
{
//
// This contract now has the funds requested.
// Your logic goes here.
//
// At the end of your logic above, this contract owes
// the flashloaned amounts + premiums.
// Therefore ensure your contract has enough to repay
// these amounts.
// Approve the LendingPool contract allowance to *pull* the owed amount
uint amountOwed = amount.add(premium);
FAUCET.mint(asset,premium);
IERC20(asset).approve(address(POOL), amountOwed);
return true;
}
function executeFlashLoan(
address asset,
uint256 amount
) public {
address receiverAddress = address(this);
bytes memory params = "";
uint16 referralCode = 0;
POOL.flashLoanSimple(
receiverAddress,
asset,
amount,
params,
referralCode
);
}
}

Ethernaut level 24 - Puzzle Wallet: to which contract the wallet object on the browser console refers to?

I got a little confused when trying to solve this level and I got even more confused when I read this solution.
I thought that the contract object loaded in the browser console was the PuzzleWallet contract, because when I look at its ABI, there are all the functions from that contract and none from the PuzzleProxy. And the PuzzleWallet does not inherit from any other contract. I don't understand how it is possible to call proposeNewAdmin() function from the PuzzleProxy contract, if it does not inherit from PuzzleProxy...
On the other hand, if the contract object in the browser console is the PuzzleProxy, why there are all the functions from the PuzzleWallet in the ABI and none from the PuzzleProxy?
Here is the Ethernaut level.
The contracts are:
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "#openzeppelin/contracts/math/SafeMath.sol";
import "#openzeppelin/contracts/proxy/UpgradeableProxy.sol";
contract PuzzleProxy is UpgradeableProxy {
address public pendingAdmin;
address public admin;
constructor(address _admin, address _implementation, bytes memory _initData) UpgradeableProxy(_implementation, _initData) public {
admin = _admin;
}
modifier onlyAdmin {
require(msg.sender == admin, "Caller is not the admin");
_;
}
function proposeNewAdmin(address _newAdmin) external {
pendingAdmin = _newAdmin;
}
function approveNewAdmin(address _expectedAdmin) external onlyAdmin {
require(pendingAdmin == _expectedAdmin, "Expected new admin by the current admin is not the pending admin");
admin = pendingAdmin;
}
function upgradeTo(address _newImplementation) external onlyAdmin {
_upgradeTo(_newImplementation);
}
}
contract PuzzleWallet {
using SafeMath for uint256;
address public owner;
uint256 public maxBalance;
mapping(address => bool) public whitelisted;
mapping(address => uint256) public balances;
function init(uint256 _maxBalance) public {
require(maxBalance == 0, "Already initialized");
maxBalance = _maxBalance;
owner = msg.sender;
}
modifier onlyWhitelisted {
require(whitelisted[msg.sender], "Not whitelisted");
_;
}
function setMaxBalance(uint256 _maxBalance) external onlyWhitelisted {
require(address(this).balance == 0, "Contract balance is not 0");
maxBalance = _maxBalance;
}
function addToWhitelist(address addr) external {
require(msg.sender == owner, "Not the owner");
whitelisted[addr] = true;
}
function deposit() external payable onlyWhitelisted {
require(address(this).balance <= maxBalance, "Max balance reached");
balances[msg.sender] = balances[msg.sender].add(msg.value);
}
function execute(address to, uint256 value, bytes calldata data) external payable onlyWhitelisted {
require(balances[msg.sender] >= value, "Insufficient balance");
balances[msg.sender] = balances[msg.sender].sub(value);
(bool success, ) = to.call{ value: value }(data);
require(success, "Execution failed");
}
function multicall(bytes[] calldata data) external payable onlyWhitelisted {
bool depositCalled = false;
for (uint256 i = 0; i < data.length; i++) {
bytes memory _data = data[i];
bytes4 selector;
assembly {
selector := mload(add(_data, 32))
}
if (selector == this.deposit.selector) {
require(!depositCalled, "Deposit can only be called once");
// Protect against reusing msg.value
depositCalled = true;
}
(bool success, ) = address(this).delegatecall(data[i]);
require(success, "Error while delegating call");
}
}
}
The contract.abi object on the browser console is:
I understand the concept of proxy patterns. But I thought that it would be done via delegatecall() functions. For example, the addToWhiteList() function on the PuzzleWallet contract would be called by a function as follows on the PuzzleProxy contract:
function addToWhitelist(address _add) external {
puzzleWalletAddress.delegatecall(abi.encodeWithSignature("addToWhitelist(address)", _add);)
}
Hopefully my question here is not as confusing as I got while trying to solve this level :)
Appreciate very much if anyone coould help me! Thanks!
I also got confused by the same thing :)
The answer is that they created the Web3 contract object with the ABI of the logic contract but with the address of the proxy contract so you can interact with the logic as if there wasn't a proxy pattern under the hood.
In reality it is calling the proxy contract with the data of a function of the logic contract. As the function doesn't exist in the proxy, its fallback function runs and redirects the call to the logic contract via delegatecall.
So if you want to call proposeNewAdmin() in the proxy, call the contract mounted in the console (aka the proxy contract) but instead of using any function from the ABI defined there (which is the logic abi), make a generic transaction calling proposeNewAdmin(). As the function does exist in the proxy, it won't trigger the fallback.
web3.eth.abi.encodeFunctionSignature("proposeNewAdmin(address)");
> '0xa6376746'
web3.eth.abi.encodeParameter("address", player);
> '0x000000000000000000000000c3a005e15cb35689380d9c1318e981bca9339942'
contract.sendTransaction({ data: '0xa6376746000000000000000000000000c3a005e15cb35689380d9c1318e981bca9339942' });

How to call a method from a contract that was instantiated from another contract via truffle console?

I'm trying to call a method from a contract that was instantiated from another contract. I use truffle console.
Here are the details: (I think you can gloss over the code, since this question is aimed at using truffle console, not fixing any bugs)
I have a contract called MyCoinSupply.sol:
pragma solidity ^0.8.0;
import "./MyCoin.sol";
contract MyCoinSupply is MyCoin("MyCoin", "MYC") // MyCoin is ERC20
{
constructor() public // gives 1000 tokens to the owner
{
_mint(msg.sender, 1000);
}
function getCoinbase() public returns (address) // for debugging purposes
{
return block.coinbase;
}
function _mintMinerReward() internal // gives 20 tokens to the miner
{
// _mint(block.coinbase, 20); // for some reason, block.coinbase is address 0
}
function _transfer(address from, address to, uint256 value) override internal
{
_mintMinerReward();
super._transfer(from, to, value);
}
}
I instantiate MyCoinSupply.sol within MyCoinDEX.sol:
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./MyCoinSupply.sol";
contract MyCoinDEX
{
IERC20 public token;
event Bought(uint256 amount);
event Sold(uint256 amount);
constructor() public
{
token = new MyCoinSupply();
}
function showSender() public view returns (address) // for debugging purposes
{
return (msg.sender);
}
function buy(uint256 amountTobuy) payable public // send ether and get tokens in exchange; 1 token == 1 ether
{
uint256 dexBalance = token.balanceOf(address(this));
require(amountTobuy > 0, "You need to send some ether");
require(amountTobuy <= dexBalance, "Not enough tokens in the reserve");
token.transfer(msg.sender, amountTobuy);
emit Bought(amountTobuy);
}
function sell(uint256 amount) public // send tokens to get ether back
{
require(amount > 0, "You need to sell at least some tokens");
uint256 allowance = token.allowance(msg.sender, address(this));
require(allowance >= amount, "Check the token allowance");
token.transferFrom(msg.sender, address(this), amount);
payable(msg.sender).transfer(amount);
emit Sold(amount);
}
}
Here's my migration for deploying contracts:
const MyCoinSupply = artifacts.require("MyCoinSupply");
const MyCoinDEX = artifacts.require("MyCoinDEX");
module.exports = function(deployer) {
deployer.deploy(MyCoinSupply);
deployer.deploy(MyCoinDEX);
};
Here's my problem:
When I try to call functions that belong to MyCoinDEX, all works well:
truffle(development)> let instance = await MyCoinDEX.deployed()
undefined
truffle(development)> instance.buy(1)
All is good here.
However, when I try the following I get an error:
truffle(development)> instance.token.balanceOf("0xE1994C1054f9c4171B8ae9a7E7a68F404c2bF829")
evalmachine.<anonymous>:0
instance.token.balanceOf("0xE1994C1054f9c4171B8ae9a7E7a68F404c2bF829")
^
Uncaught TypeError: instance.token.balanceOf is not a function
I Googled this error (I read this solution and this solution), but I didn't really stumble upon a solution. Can someone tell me how can I call token's methods from MyCoinDEX?
Thank you in advance!

Calling a public method in smart contract with Web3.js version: '1.0.0-beta.46'

I started first steps into ethereum blockchain with parity on a private network. I was able to configure parity and perform the deployment of smart contract on a dev mode chain on my private network through Parity UI which also is able to call methods of the contract.
The problem that I face is related to calling a function in smart contract using Web3.js. I was able to connect to the chain using the Web.js Library;
Web3 = require('web3')
web3 = new Web3('ws://localhost:8546')
mycontract = web3.eth.Contract([{"constant":false,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}],0xEb112542a487941805F7f3a04591F1D6b04D513c)
When I call the method below;
mycontract.methods.greet().call()
It gives me the following output instead of returning the expected string "OK Computer" through a promise object as written in smart contract greet function.
{ [Function: anonymousFunction]
send: { [Function] request: [Function] },
estimateGas: [Function],
encodeABI: [Function] }
Smart Contract code:
pragma solidity ^0.4.22;
//Compiler Version: 0.4.22
contract Greeter {
address owner;
constructor() public {
owner = msg.sender;
}
function greet() public returns(string){
return "OK Computer";
}
}
Every transaction or smart contract method call which involves a change on the blockchain state will return a promise. So you just need to handle the promise accordingly:
mycontract.methods.greet.call().then(function(resp) {
console.log(resp) // This will output "OK Computer"
}
More in web docs

how to get error message from contract modifier in UI?

When testing a contract on Remix I notice if a method does not pass a modifier you actually see the error message shown in the window below the contract code. Is this something I can get from web3, or how can I in my own UI get this error messages from the contract when provided?
Here is a simple contract:
address public owner;
modifier onlyOwner() {
require(msg.sender == owner, "Owner account is required");
_;
}
constructor() public {
owner = msg.sender;
}
function doStuff()
external
view
onlyOwner
returns (bool) {
return true;
}
When I call the contract not from owner in remix, in the console I get this message:
call to Contract.doStuff errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Reason provided by the contract: "Owner account is required". Debug the transaction to get more information.
Is the error it gives something I can get from a web3 transaction? I do not see it