Can not verify Smart Contract with #chainlink - remix

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);
}
}

Related

How to block bot from stealing deposited eth in smart contract

I am working on smart contract for a simple payment system where u deposit and get a code. Then u can give a code to anyone and they can withdraw to any address.
I have already tested on all testnets and it works fine.
But on ethereum mainnet as soon as I deposit the eth, it is stolen and transferred by a mev bot.
//SPDX-License-Identifier: UNLICENSED
// It will be used by the Solidity compiler to validate its version.
pragma solidity ^0.8.9;
// We import this library to be able to use console.log
import "hardhat/console.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
contract Payment is Ownable {
address payable public feeWallet;
uint256 public feeAmount;
uint256 private numberOfDeposits = 0;
struct Deposit {
uint256 time;
bytes32 id;
uint256 amount;
}
// mapping(address => bytes32[]) public addressToHashes;
mapping(bytes32 => uint256) public hashToAmount;
mapping(address => Deposit[]) public addressToDeposits;
mapping(bytes32 => bool) public isWithdrawn;
event DepositCreated(address _payer, uint256 _amount);
event DepositWithdrawn(
address _withdrawer,
uint256 _amount,
address indexed _withdrawTo
);
constructor(address _feeWallet) {
feeWallet = payable(_feeWallet);
}
function createDeposit(string memory _id) public payable returns (bytes32) {
//Check if value is greater than 0
require(msg.value > 0, "Amount cannot be equal to 0");
//Fetch mapppings
Deposit[] storage deposits = addressToDeposits[msg.sender];
//Create Hash from id
bytes32 hash = generateId(_id);
//Update Mappings
hashToAmount[hash] = msg.value;
numberOfDeposits += 1;
deposits.push(Deposit(block.timestamp, hash, msg.value));
addressToDeposits[msg.sender] = deposits;
emit DepositCreated(msg.sender, msg.value);
return hash;
}
function generateId(string memory _id) internal view returns (bytes32) {
uint id = uint(
keccak256(
abi.encodePacked(
_id,
block.difficulty,
block.timestamp,
numberOfDeposits
)
)
);
return bytes32(id % 100000000000000);
}
function checkDepositExist(uint _id) public view returns (bool) {
bytes32 hash = bytes32(_id);
uint256 amount = hashToAmount[hash];
console.log("amount", amount);
if (amount > 0) {
return true;
} else {
return false;
}
}
function viewDeposit(uint _id) public view returns (uint256) {
bytes32 hash = bytes32(_id);
uint256 amount = hashToAmount[hash];
return amount;
}
function withdrawDeposit(uint _id, address _to) public {
require(checkDepositExist(_id), "ID invalid");
bytes32 hash = bytes32(_id);
uint256 amount = hashToAmount[hash] - feeAmount;
hashToAmount[hash] = 0;
(bool sent, bytes memory data) = payable(_to).call{value: amount}("");
require(sent, "Failed to send deposit amount");
require(sendFees(), "Failed to send fee amount");
isWithdrawn[hash] = true;
emit DepositWithdrawn(msg.sender, amount, _to);
}
function getUserDeposits() public view returns (Deposit[] memory) {
Deposit[] memory deposits = addressToDeposits[msg.sender];
return deposits;
}
function setFeeAmount(uint _amount) public onlyOwner {
feeAmount = _amount;
}
function setFeeWallet(address _wallet) public onlyOwner {
feeWallet = payable(_wallet);
}
function sendFees() internal returns (bool) {
(bool sent, bytes memory data) = payable(feeWallet).call{
value: feeAmount
}("");
return sent;
}
}
Here's the transaction of eth being stolen https://etherscan.io/tx/0xd4f92a3346ff51cf41c40b47b1270eda5ca57c4aaae2b3c9858298d8c6269725
I can point out many vulnerabilities that this smart contract has.
One of them is that there is no private data in a smart contract. Anybody can read the data in the storage of a smart contract. In this case, I see that hashToAmount has the hashes that you send to the user who created the deposit. But this can be read by anyone (using something like web3.eth.getStorageAt(contractAddress, storageIndex)) and call the withdrawDeposit function and steal the funds.
Something else, miners can temper with some blockchain data, like the timestamp, etc. Miners can see the _id that is being sent to the createDeposit and use it to immediately steal the funds from the contract.
Also, I see a lack of checks in the withdrawDeposit function.
I suggest that you use well known patterns and modifiers and other checks. Relying more on things like msg.sender since nobody can fake or tamper with msg.sender value. The sender is always the user that created the request, and if the sender is the owner of some ether, than only they can withdraw it.
Instead of checking the balance of that hash, save the msg.sender in the mapping instead when someone makes a deposit. Then, while withdrawing, check that the msg.sender has balance and if so, send the balance to the _to address.
Also, check for reentrancy attacks in your withdrawDeposit deposit function.
Trying to generate an id in a smart contract with the block data is not that secure. There are oracle libraries that can help you get a pseudo-random number from outside of the contract, but again, it can be read by a miner before the transaction is included in a block and compromise your funds.
I'm not sure if any of these are causing your problem exactly, but I'm sure that all of these could be potential issues for your contract.
I recommend you follow security standard patterns like from OpenZeppelin: https://www.openzeppelin.com/.

Lesson6 full blockchain solidity course: fund_and_withdraw - ValueError: Gas estimation failed

I am following along full blockchain solidity course.
I am trying to deploy fund_and_withdraw.py to Rinkeby using brownie but I run into the follwoing error:
ValueError: Gas estimation failed: 'execution reverted: You need to spend more ETH!'. This transaction will likely revert. If you wish to broadcast, you must set the gas limit manually.
I previously tried deploying it on ganache-cli but get a "Index out of range" issue as described on my previous issue.
Now, I am trying to run it on Rinkeby (Ganache UI is not connecting to my Brownie and is throwing off the entire contract) but it returns the "ValueError".
Also, tried changing the decimals in FundMe.py.
I tried deploying on Rinkby and I no longer get "Index out of range" but instead i get "ValueError"
My code below:
fund_and_withdraw
from brownie import FundMe
from scripts.helpful_scripts import get_account
def fund():
fund_me = FundMe[-1]
account = get_account()
entrance_fee = fund_me.getEntranceFee()
print(entrance_fee)
print(f"The current entry fee is {entrance_fee}")
print("funding")
fund_me.fund(
{
"from": account,
"value": entrance_fee,
}
)
# 0.025000000000000000
def main():
fund()
Helpful_scripts.py
from brownie import network, config, accounts, MockV3Aggregator
from web3 import Web3
# Create Variable to store dev network list (Ex: ["development", "ganache", etc...])
LOCAL_BLOCKCHAIN_ENVIRONMENTS = "development"
DECIMALS = 8
STARTING_PRICE = 200000000000
def get_account():
# if network.show_active == "development":
if network.show_active() in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
return accounts[0]
else:
return accounts.add(config["wallets"]["from_key"])
def deploy_mocks():
print(f"The active network is {network.show_active()}")
print("Deploying Mocks...")
if len(MockV3Aggregator) <= 0:
MockV3Aggregator.deploy(
# DECIMALS, Web3.toWei(STARTING_PRICE, "ether"), {"from": get_account()}
DECIMALS,
STARTING_PRICE,
{"from": get_account()},
)
print("Mocks Deployed!")
FundMe.py
contract FundMe {
using SafeMath96 for uint256;
mapping(address => uint256) public addressToAmountFunded;
address[] public funders;
address public owner;
AggregatorV3Interface public priceFeed;
//constructor(address _priceFeed) public {
constructor(address _priceFeed) {
priceFeed = AggregatorV3Interface(_priceFeed);
owner = msg.sender;
}
function fund() public payable {
uint256 minimumUSD = 50 * 10**18;
require(
getConversionRate(msg.value) >= minimumUSD,
"You need to spend more ETH!"
);
addressToAmountFunded[msg.sender] += msg.value;
funders.push(msg.sender);
}
function getVersion() public view returns (uint256) {
return priceFeed.version();
}
function getPrice() public view returns (uint256) {
(, int256 answer, , , ) = priceFeed.latestRoundData();
//return uint256(answer * 10000000000);
return uint256(answer * 100000000);
}
// 1000000000
function getConversionRate(uint256 ethAmount)
public
view
returns (uint256)
{
uint256 ethPrice = getPrice();
//uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
uint256 ethAmountInUsd = (ethPrice * ethAmount) / 100000000;
return ethAmountInUsd;
}
function getEntranceFee() public view returns (uint256) {
// minimumUSD
uint256 minimumUSD = 50 * 10**18;
uint256 price = getPrice();
uint256 precision = 1 * 10**18;
// return (minimumUSD * precision) / price;
// We fixed a rounding error found in the video by adding one!
return ((minimumUSD * precision) / price) + 1;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
function withdraw() public payable onlyOwner {
payable(msg.sender).transfer(address(this).balance);
for (
uint256 funderIndex = 0;
funderIndex < funders.length;
funderIndex++
) {
address funder = funders[funderIndex];
addressToAmountFunded[funder] = 0;
}
funders = new address[](0);
}
}
Thank you!
Your require statement is failing in this line:
require(
getConversionRate(msg.value) >= minimumUSD,
"You need to spend more ETH!"
);
This probably means that you don't have enough ether in your wallet to send to the contract. So fund your wallet with more ether and it will probably work if you deployed the contract correctly.
The index out of range is probably a fault in your get_account() function it seems. The LOCAL_BLOCKCHAIN_ENVIRONMENTS should be an array not a string. It also doesn't contain the ganache-local so you are trying to use your private key for your local blockchain that is probably why you are getting index out of range.
So fix your LOCAL_BLOCKCHAIN_ENVIRONMENTS to look like this:
LOCAL_BLOCKCHAIN_ENVIRONMENTS = ["development", "ganache-local"]
I guess it should work then.
from brownie import FundMe
from scripts.helpful_scripts import get_account
def fund():
_priceFeed = 0x8A753747A1Fa494EC906cE90E9f37563A8AF630e
account = get_account()
fund_me = FundMe.deploy(_priceFeed , {"from": account})
**_priceFeed is in your constructor , so you should pass it to your
contract for deploy, i added it as hardcode , but its better to use yaml
file for projects **
entrance_fee = fund_me.getEntranceFee()
print(entrance_fee)
print(f"The current entry fee is {entrance_fee}")
print("funding")
fund_tx = fund_me.fund(
{
"from": account,
"value": entrance_fee,
}
)
# 0.025000000000000000
fund_tx.wait(1)
** when you use functions that make transaction(not reading) , its better
to use wait() method , its help your transaction to write in block **
def main():
fund()

Chainlink API call job not fulfilled - tutorial

I have been trying to learn how to make a GET request using Chainlink.
I was watching this tutorial: https://www.youtube.com/watch?v=ay4rXZhAefs and I used the exact same code that they used in the video and I also followed the same steps using Remix (I have my metamask (Kovan) open with enough ETH and LINK and I also funded my contract with enough LINK). However after I call requestVolumeData() the volume variable doesn't update and stays 0.
I have tried to use different networks and oracles/jobs, but I seem to run into the same issue over and over again. Any help would be appreciated.
pragma solidity ^0.6.0;
import "#chainlink/contracts/src/v0.6/ChainlinkClient.sol";
/**
* THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.
* PLEASE DO NOT USE THIS CODE IN PRODUCTION.
*/
contract APIConsumer is ChainlinkClient {
using Chainlink for Chainlink.Request;
uint256 public volume;
address private oracle;
bytes32 private jobId;
uint256 private fee;
/**
* Network: Kovan
* Oracle: 0x2f90A6D021db21e1B2A077c5a37B3C7E75D15b7e
* Job ID: 29fa9aa13bf1468788b7cc4a500a45b8
* Fee: 0.1 LINK
*/
constructor() public {
setPublicChainlinkToken();
oracle = 0x2f90A6D021db21e1B2A077c5a37B3C7E75D15b7e;
jobId = "29fa9aa13bf1468788b7cc4a500a45b8";
fee = 0.1 * 10 ** 18; // (Varies by network and job)
}
/**
* Create a Chainlink request to retrieve API response, find the target
* data, then multiply by 1000000000000000000 (to remove decimal places from data).
*/
function requestVolumeData() public returns (bytes32 requestId)
{
Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
// Set the URL to perform the GET request on
request.add("get", "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD");
// Set the path to find the desired data in the API response, where the response format is:
// {"RAW":
// {"ETH":
// {"USD":
// {
// "VOLUME24HOUR": xxx.xxx,
// }
// }
// }
// }
request.add("path", "RAW.ETH.USD.VOLUME24HOUR");
// Multiply the result by 1000000000000000000 to remove decimals
int timesAmount = 10**18;
request.addInt("times", timesAmount);
// Sends the request
return sendChainlinkRequestTo(oracle, request, fee);
}
/**
* Receive the response in the form of uint256
*/
function fulfill(bytes32 _requestId, uint256 _volume) public recordChainlinkFulfillment(_requestId)
{
volume = _volume;
}
// function withdrawLink() external {} - Implement a withdraw function to avoid locking your LINK in the contract
}
Are you giving some time to let the node fetch the request? When you do this example, you usually have to click the requestVolumeData() button, multiple times, waiting for the node to fulfill the request. Less than two minutes usually.
Here's another more recent version of that example contract. It's nearly the same.
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.6;
import "#chainlink/contracts/src/v0.6/ChainlinkClient.sol";
contract APIConsumer is ChainlinkClient {
uint256 public volume;
address private oracle;
bytes32 private jobId;
uint256 private fee;
/**
* Network: Kovan
* Oracle: 0x2f90A6D021db21e1B2A077c5a37B3C7E75D15b7e
* Job ID: 29fa9aa13bf1468788b7cc4a500a45b8
* Fee: 0.1 LINK
*/
constructor(address _oracle, string memory _jobId, uint256 _fee, address _link) public {
if (_link == address(0)) {
setPublicChainlinkToken();
} else {
setChainlinkToken(_link);
}
// oracle = 0x2f90A6D021db21e1B2A077c5a37B3C7E75D15b7e;
// jobId = "29fa9aa13bf1468788b7cc4a500a45b8";
// fee = 0.1 * 10 ** 18; // 0.1 LINK
oracle = _oracle;
jobId = stringToBytes32(_jobId);
fee = _fee;
}
/**
* Create a Chainlink request to retrieve API response, find the target
* data, then multiply by 1000000000000000000 (to remove decimal places from data).
*/
function requestVolumeData() public returns (bytes32 requestId)
{
Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
// Set the URL to perform the GET request on
request.add("get", "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD");
// Set the path to find the desired data in the API response, where the response format is:
// {"RAW":
// {"ETH":
// {"USD":
// {
// "VOLUME24HOUR": xxx.xxx,
// }
// }
// }
// }
request.add("path", "RAW.ETH.USD.VOLUME24HOUR");
// Multiply the result by 1000000000000000000 to remove decimals
int timesAmount = 10**18;
request.addInt("times", timesAmount);
// Sends the request
return sendChainlinkRequestTo(oracle, request, fee);
}
/**
* Receive the response in the form of uint256
*/
function fulfill(bytes32 _requestId, uint256 _volume) public recordChainlinkFulfillment(_requestId)
{
volume = _volume;
}
function stringToBytes32(string memory source) public pure returns (bytes32 result) {
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly {
result := mload(add(source, 32))
}
}
}

Struct on delegatecall as an argument

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)

How can I compile atom code through terminal using truffle?

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);
}
}

Resources