I trying to compile my atom code through the Mac terminal and I received this error:
Error parsing /Users/owner/Desktop/contracts/contracts/ApprovalContracts.sol: ParsedContract.sol:6:36: ParserError: Expected primary expression.
address public constant approver = ; ^
Compilation failed. See above.
I need to compile my code from atom using the terminal truffle compile.
Here is the code:
pragma solidity ^0.4.18;
contract ApprovalContracts {
address public sender;
address public receiver;
address public constant approver =;
function deposit(address _receiver) external payable {
require(msg.value > 0);
sender = msg.sender;
receiver = receiver;
}
function viewApprover() external pure return(address) {
return(approver);
}
function approve() external {
require(msg.sender == approver);
receiver.transfer(address(this).balance);
}
}
There are a few problems with your code.
You have to initialize the constant variable approver with a value.
On line 12, the code should be receiver = _receiver;
On line 15, it should be returns(address) instead of return(address)
The final code should be something like this
pragma solidity ^0.4.18;
contract ApprovalContracts {
address public sender;
address public receiver;
address public constant approver=some-address-here-without-quotes;
function deposit(address _receiver) external payable {
require(msg.value > 0);
sender = msg.sender;
receiver = _receiver;
}
function viewApprover() external pure returns(address) {
return(approver);
}
function approve() external {
require(msg.sender == approver);
receiver.transfer(address(this).balance);
}
}
Related
I implemented the smart contract as follows.
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
contract Trade {
enum TradeState {
Start,
Proceeding,
Shipping,
Cancel,
Complete,
Return
}
address payable public seller;
address payable public buyer;
uint256 public productID;
uint256 public price;
uint256 public trackingNumber;
uint256 public depositAmount;
TradeState public currentTradeState;
constructor(address _buyer, uint256 _productID, uint256 _price) payable {
seller = payable(msg.sender);
depositAmount = msg.value;
buyer = payable(_buyer);
productID = _productID;
price = _price; // * (10 ** 18);
trackingNumber = 0;
currentTradeState = TradeState.Start;
}
function setTrackingNumber(uint256 _trackingNumber) public {
require(msg.sender == seller);
trackingNumber = _trackingNumber;
currentTradeState = TradeState.Shipping;
}
function makePayment() public payable returns (bool result) {
require(msg.sender == buyer && msg.value == price, "Not enough ETH");
currentTradeState = TradeState.Proceeding;
return true;
}
function completeTrade() public payable {
require(msg.sender == buyer, "msg.sender is not buyer!");
require(trackingNumber != 0, "trackingNumber has not been set.");
seller.transfer(price + depositAmount);
if (address(this).balance > 0) {
buyer.transfer(address(this).balance);
}
currentTradeState = TradeState.Complete;
}
function cancel() public payable {
require(currentTradeState != TradeState.Shipping, "Already shipped.");
//buyer.transfer(price);
seller.transfer(depositAmount);
if (address(this).balance > 0) {
buyer.transfer(address(this).balance);
}
currentTradeState = TradeState.Cancel;
}
function returnProduct() public payable {
require(msg.sender == buyer, "caller must be buyer.");
buyer.transfer(address(this).balance);
currentTradeState = TradeState.Return;
}
function transferWithoutPayingFee(address payable addr, uint256 amount) internal {
addr.transfer(amount);
}
}
Then, the contract was deployed and accessed using the ethers.js library.
There is no problem with contract deployment and accessing other methods.
However, when sending a transaction that calls cancel() or returnProduct(), it is not executed normally with the following error.
The two methods are called as follows.
async function cancel(contractAddress, privateKey) {
let wallet = new ethers.Wallet(privateKey, provider);
let contract = new ethers.Contract(contractAddress, contractABI, provider);
let contractWithSigner = contract.connect(wallet);
let tx = await contractWithSigner.cancel(option);
await tx.wait();
}
async function returnProduct(contractAddress, privateKey) {
let wallet = new ethers.Wallet(privateKey, provider);
let contract = new ethers.Contract(contractAddress, contractABI, provider);
let contractWithSigner = contract.connect(wallet);
let tx = await contractWithSigner.returnProduct();
await tx.wait();
}
The error log that occurs is as follows.
Error: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (error={"reason":"processing response error","code":"SERVER_ERROR","body":"{\"id\":65,\"jsonrpc\":\"2.0\",\"error\":{\"message\":\"VM Exception while processing transaction: revert\",\"code\":-32000,\"data\":{\"stack\":\"RuntimeError: VM Exception while processing transaction: revert\\n at Function.RuntimeError.fromResults (C:\\\\Program Files\\\\WindowsApps\\\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\\\app\\\\resources\\\\static\\\\node\\\\node_modules\\\\ganache-core\\\\lib\\\\utils\\\\runtimeerror.js:94:13)\\n at module.exports (C:\\\\Program Files\\\\WindowsApps\\\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\\\app\\\\resources\\\\static\\\\node\\\\node_modules\\\\ganache-core\\\\lib\\\\utils\\\\gas\\\\guestimation.js:142:32)\",\"name\":\"RuntimeError\"}}}","error":{"code":-32000,"data":{"stack":"RuntimeError: VM Exception while processing transaction: revert\n at Function.RuntimeError.fromResults (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\utils\\runtimeerror.js:94:13)\n at module.exports (C:\\Program Files\\WindowsApps\\GanacheUI_2.5.4.0_x64__5dg5pnz03psnj\\app\\resources\\static\\node\\node_modules\\ganache-core\\lib\\utils\\gas\\guestimation.js:142:32)","name":"RuntimeError"}},"requestBody":"{\"method\":\"eth_estimateGas\",\"params\":[{\"gasPrice\":\"0x4a817c800\",\"from\":\"0xb55a7a6d8cf909e938cd003c453ea7987fd4014a\",\"to\":\"0x21436e17d53fc0e34609883ad095c3c6d0ad79e5\",\"data\":\"0x056baaba\"}],\"id\":65,\"jsonrpc\":\"2.0\"}","requestMethod":"POST","url":"HTTP://127.0.0.1:7545"}, tx={"data":"0x056baaba","to":{},"from":"0xB55A7A6d8cf909E938cd003c453ea7987fd4014a","gasPrice":{"type":"BigNumber","hex":"0x04a817c800"},"type":0,"nonce":{},"gasLimit":{},"chainId":{}}, code=UNPREDICTABLE_GAS_LIMIT, version=abstract-signer/5.6.2)
at Logger.makeError (C:\Users\yang\Desktop\졸업과제\Offchain-Backend\node_modules\#ethersproject\logger\lib\index.js:233:21)
at Logger.throwError (C:\Users\yang\Desktop\졸업과제\Offchain-Backend\node_modules\#ethersproject\logger\lib\index.js:242:20)
at C:\Users\yang\Desktop\졸업과제\Offchain-Backend\node_modules\#ethersproject\abstract-signer\lib\index.js:365:47
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Promise.all (index 6) {
reason: 'cannot estimate gas; transaction may fail or may require manual gas limit',
code: 'UNPREDICTABLE_GAS_LIMIT',
...
When the test code was written and tested on the truffle framework, it worked normally. My guess is that require(...) seems to be causing the problem. Please advise on how to solve this problem.
I'm Solidity Newbie.
I'm learning how to implement Transparent Proxy using Openzeppelin's TransparentUpgradeableProxy contract, but am having some problems.
Step 1: I tried to deploy a simple contract MyConV0, then implemented deploy and call method, everything is fine.
// File MyConV0.sol
pragma solidity ^0.8.0;
import "hardhat/console.sol";
contract MyConV0 {
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) public {
_name = name_;
_symbol = symbol_;
console.log(_symbol);
}
function symbol() public view returns (string memory) {
console.log(_symbol);
return _symbol;
}
function name() public view returns (string memory) {
console.log('Name: ');
console.log(_name);
return _name;
}
function getVersion() pure external returns(uint256) {
return 0;
}
}
Step 2: I tried to upgrade to MyConV1 to be able to Upgradable with TransparentUpgradeableProxy but failed.
// File: MyConV1
pragma solidity ^0.8.0;
import "#openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "#openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "#openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "hardhat/console.sol";
contract MyConV1 is Initializable, OwnableUpgradeable {
string private _name;
string private _symbol;
function initialize(string memory name_, string memory symbol_) initializer public {
__Ownable_init();
_name = name_;
_symbol = symbol_;
console.log(_symbol);
}
function symbol() public view returns (string memory) {
console.log('Symbol: ');
console.log(_symbol);
return _symbol;
}
function name() public view returns (string memory) {
console.log('Name: ');
console.log(_name);
return _name;
}
function getVersion() pure external returns(uint256) {
return 1;
}
}
Refer TransparentUpgradableProxy: https://docs.openzeppelin.com/contracts/4.x/api/proxy#TransparentUpgradeableProxy
// The test file in JS using ethers.js and Hardhat environment
async function main() {
let t0, t1, t2, t3, t4, v1, v2, v3, v4;
const [owner, proxyAdmin, user, other] = await ethers.getSigners();
// --- 0. Deploy MyConV0
let input0 = [ 'TotoName', 'Toto' ];
let con0 = await deploy_verify_contract("MyConV0", input0);
t0 = await con0.symbol() ;
console.log(t0); // worked -> Toto
// --- 1. Deploy MyConV1
let input1 = [ ];
let con1 = await deploy_verify_contract("MyConV1", input1);
// --- 2. get data
let abi = [ `function initialize( string name_,
string symbol_,
)` ];
let iface = new ethers.utils.Interface(abi);
let data = iface.encodeFunctionData("initialize", [ 'TotoName', 'Toto' ]);
// --- 3. deploy trans proxy
let input2 = [ con1.address, owner.address, data ];
let con2 = await deploy_verify_contract("TransparentUpgradeableProxy1", input2);
// --- 4. call proxy method
t2 = await con2.implementation();
console.log(t2); // DO NOT WORK, t2 is object tx, and do not contains the results like step 0
// --- 5. call MyConV1 contact via proxy -> ERROR: "TypeError: con2.symbol is not a function"
t3 = await con2.symbol();
console.log(t3);
}
async function deploy_verify_contract(contractName, input, lib = {}){
const _contract = await hre.ethers.getContractFactory(contractName, lib);
const contract = await _contract.deploy(...input);
await contract.deployed();
console.log( contractName + " deployed to:", contract.address );
return contract;
}
I used Hardhat's console.log function and it seems to have successfully deployed the Proxy, and sent the correct data to the MyConV1.initialize function, but don't know how to call the proxy properly. Specifically with the above code, I don't understand a few points:
Have I deployed the proxy correctly?
Why can't I get the correct return data of the proxy's implementation() function?
Why can't I call MyConV1's function through the proxy?
Hope you guys can help me how to correct the code, I have not been able to solve this problem for a few days.
You are not calling UpgradeTo() on proxy contract to set the implementation contract's address. After you have set the implementation contract in proxy you have to initialise the implementation contract via proxy contract only! not any other way or directly calling it on implementation contract (it wont work!!)
I have followed the ideas I saw on the internet:
UpdateColumnIndexVector(m_vColumnIndexesToExclude, WriteColumnIndexesToExclude);
That calls:
void CCreateReportDlg::UpdateColumnIndexVector(ColumnIndexVector &rvData, std::function<void()> WriteToRegistry)
{
bool bModified = true;
// Code simplified
if (bModified)
{
WriteToRegistry();
}
}
The function being passed in:
void CCreateReportDlg::WriteColumnIndexesToExclude()
{
ByteVector vData(m_vColumnIndexesToExclude.begin(), m_vColumnIndexesToExclude.end()); // int to BYTE
const CString strSection = theApp.GetActiveScheduleSection(_T("Options"));
theApp.WriteProfileVector(strSection, _T("AssignStatesEx"), vData);
}
When I compile:
error C3867: CCreateReportDlg::WriteColumnIndexesToExclude: non-standard syntax; use & to create a pointer to member
Yet, if I change this line to:
UpdateColumnIndexVector(m_vColumnIndexesToExclude, &WriteColumnIndexesToExclude);
That does not compile either:
error C2276: &: illegal operation on bound member function expression
error C2660: CCreateReportDlg::UpdateColumnIndexVector: function does not take 1 arguments
WriteColumnIndexesToExclude is a private member of the dialog class.
What am I doing wrong?
PS. My project is MFC C++ Dialog.
I can not verify my test smart contract on BSC Main Network using #chainlink.
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.7;
import "#chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
contract PriceTest {
AggregatorV3Interface internal priceFeed;
constructor() public {
priceFeed = AggregatorV3Interface(0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE); // for BSC Main Net
}
function getLatestPrice() public view returns (uint256) {
(,int price,,,) = priceFeed.latestRoundData();
return uint256(price/100000000);
}
}
What I have done :
Make Flattened file and put in the contract code using truffle-flattener. I did it before for a test net and it's ok.
Copy ABI from remix and pasted to abi.hashex.org
But I tried many time end up with problem in verifying the contract. I think I am not really understand how to put constructor parameter correctly to get the ABI auto-parse.
I am quite new to smart contract. Need learn more from experts.
My contract :
https://bscscan.com/address/0x0849a15338a5f0787696cea335757b608ff92a85
Flattened file :
// File: #chainlink\contracts\src\v0.6\interfaces\AggregatorV3Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
interface AggregatorV3Interface {
function decimals()
external
view
returns (
uint8
);
function description()
external
view
returns (
string memory
);
function version()
external
view
returns (
uint256
);
// getRoundData and latestRoundData should both raise "No data present"
// if they do not have data to report, instead of returning unset values
// which could be misinterpreted as actual reported values.
function getRoundData(
uint80 _roundId
)
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
}
// File: contracts\Getprice.sol
pragma solidity ^0.6.7;
contract PriceTest {
AggregatorV3Interface internal priceFeed;
constructor() public {
priceFeed = AggregatorV3Interface(0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE); // for BSC Main Net
}
function getLatestPrice() public view returns (uint256) {
(,int price,,,) = priceFeed.latestRoundData();
return uint256(price/100000000);
}
}
Is it possible to pass a struct as an argument to delegatecall ?
I have this function that calls delegatecall and takes a struct (a 0x quote) as an argument which is later used on the function signature and in the proper call:
function executeDelegate(address _weth, address _contract, ZrxQuote memory _zrxQuote) private returns(uint, string memory) {
console.log('spender address: ', _zrxQuote.spender); //----> testing
(bool success, ) = logicContract.delegatecall(
abi.encodeWithSignature('execute(address,address,uint256,ZrxQuote)', _weth, _contract, borrowed, _zrxQuote)
);
console.log(success);
require(success, 'Delegate Call failed');
return (0, '');
}
...but it doesn't work and returns false every time and the error Delegate Call failed.
I have this console.log('spender address: ', _zrxQuote.spender); to test if my struct is being read successfully and it is.
Also, if I remove the struct entirely of the equation (from the function, from delegatecall, from the call, from the logic contract), delegatecall works perfectly, something like:
function executeDelegate(address _weth, address _contract) private returns(uint, string memory) {
(bool success, ) = logicContract.delegatecall(
abi.encodeWithSignature('execute(address,address,uint256)', _weth, _contract, borrowed)
);
require(success, 'Delegate Call failed');
return (0, '');
}
So the problem is directly with the struct being passed to delegatecall, but I can't seem to find on any docs what the issue is (storage variables are the same).
These are the contracts:
Proxy:
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;
import "#studydefi/money-legos/dydx/contracts/DydxFlashloanBase.sol";
import "#studydefi/money-legos/dydx/contracts/ICallee.sol";
import "#openzeppelin/contracts/token/ERC20/IERC20.sol";
import "hardhat/console.sol";
contract DydxFlashloaner is ICallee, DydxFlashloanBase {
struct ZrxQuote {
address sellTokenAddress;
address buyTokenAddress;
address spender;
address swapTarget;
bytes swapCallData;
}
struct MyCustomData {
address token;
uint256 repayAmount;
}
address public logicContract;
uint public borrowed;
constructor(address _logicContract, uint _borrowed) public {
logicContract = _logicContract;
borrowed = _borrowed;
}
/******* Part that matters ******/
function callFunction(
address sender,
Account.Info memory account,
bytes memory data
) public {
(MyCustomData memory mcd, ZrxQuote memory zrx) = abi.decode(data, (MyCustomData, ZrxQuote));
uint256 balOfLoanedToken = IERC20(mcd.token).balanceOf(address(this));
require(
balOfLoanedToken >= mcd.repayAmount,
"Not enough funds to repay dydx loan!"
);
executeDelegate(mcd.token, address(this), zrx); //----> calls delegatecall
}
function executeDelegate(address _weth, address _contract, ZrxQuote memory _zrxQuote) private returns(uint, string memory) {
console.log('this is: ', _zrxQuote.spender);
(bool success, ) = logicContract.delegatecall(
abi.encodeWithSignature('execute(address,address,uint256,ZrxQuote)', _weth, _contract, borrowed, _zrxQuote)
);
console.log(success);
require(success, 'Delegate Call failed');
return (0, '');
}
/******* End ******/
function initiateFlashLoan(
address _solo,
address _token,
uint256 _amount,
address[] calldata _quoteAddr,
bytes calldata _quoteData
) external
{
ZrxQuote memory zrxQuote = ZrxQuote({
sellTokenAddress: _quoteAddr[0],
buyTokenAddress: _quoteAddr[1],
spender: _quoteAddr[2],
swapTarget: _quoteAddr[3],
swapCallData: _quoteData
});
ISoloMargin solo = ISoloMargin(_solo);
uint256 marketId = _getMarketIdFromTokenAddress(_solo, _token);
uint256 repayAmount = _getRepaymentAmountInternal(_amount);
IERC20(_token).approve(_solo, repayAmount);
Actions.ActionArgs[] memory operations = new Actions.ActionArgs[](3);
operations[0] = _getWithdrawAction(marketId, _amount);
operations[1] = _getCallAction(
abi.encode(MyCustomData({token: _token, repayAmount: repayAmount}), zrxQuote)
);
operations[2] = _getDepositAction(marketId, repayAmount);
Account.Info[] memory accountInfos = new Account.Info[](1);
accountInfos[0] = _getAccountInfo();
solo.operate(accountInfos, operations);
}
}
Logic:
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
pragma abicoder v2; //tried with pragma experimental ABIEncoderV2 also
import '#uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';
import './interfaces/MyILendingPool.sol';
import './interfaces/MyIERC20.sol';
import "hardhat/console.sol";
contract FlashLoaner {
struct ZrxQuote {
address sellTokenAddress;
address buyTokenAddress;
address spender;
address swapTarget;
bytes swapCallData;
}
struct MyCustomData {
address token;
uint256 repayAmount;
}
address public logicContract;
uint public borrowed;
function execute(address _weth, address _contract, uint256 _borrowed, ZrxQuote memory _zrxQuote) public {
console.log('hello');
//I removed the code for simplicity, but it never executes, not even the 'hello'.
}
Thanks for the help!
Solution:
Have to pass a tuple instead to abi.encodeWithSignature, according to the docs: https://docs.soliditylang.org/en/v0.8.6/abi-spec.html#mapping-solidity-to-abi-types
So it would be:
execute(address,address,uint256,(address, address, address, address, bytes))
...instead of :
execute(address,address,uint256,ZrxQuote)