0

I am trying to establish a basic reversed auction in solidity using the Remix IDE.

In the last function i want to pay back the whole contract balance to a certain address.

My approach with .transfer(address(this).balance); does not work. Compiling is fine but after deploying the contract this line is not working.

Is there another way i can "empty" the contract balance. Or do i use the wrong syntax?

Help would be much appreciated Thanks

Smart contract:

pragma solidity ^0.5.11;

contract ReverseAuction {
    
    address payable public auctioneer;
    address payable public lowestBidder;
    uint public auctionEndTime;
    uint public WTP;
    uint public lowestBid;
    bool ended;
    
    mapping(address => uint) pendingReturns;

    constructor(uint biddingTime) public payable {
        auctioneer = msg.sender;
        auctionEndTime = now + biddingTime;
        WTP = msg.value;
        lowestBid = WTP;
        ended = false;
    }

    function bid() public payable {                                         ///insurance deposit (linking with tracking contract!)
        require(now <= auctionEndTime,"Auction already ended.");
        require(msg.value < WTP,"Bid exceeds willingness to pay.");
        require(msg.value < lowestBid,"There already is a lower bid.");
        if (lowestBid != 0) {
            lowestBidder.transfer(lowestBid);
            pendingReturns[lowestBidder] += lowestBid;
            lowestBidder = msg.sender;
            lowestBid = msg.value;
        }
    }

    function AuctionEnd() public {
        require(msg.sender == auctioneer,"Insufficient permission.");
        require(now >= auctionEndTime, "Auction not yet ended.");
        require(ended == false, "AuctionEnd has already been called.");
        lowestBidder.transfer(lowestBid*2); ///paying back safety deposit + actual payment (so 2 times lowest bid)
        auctioneer.transfer(address(this).balance);  ///rest of the contract balance (WTP-lowest bid) should go back to the auctioneer
        ended = true;
    }
}

Error message:

transact to ReverseAuction.AuctionEnd 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. 
4
  • Well what is the error you get? Commented Sep 27, 2019 at 9:54
  • It is likely the error is in your code. Is the recipient address payable? Is the recipient address a contract with a complex fallback function?
    – Ismael
    Commented Sep 27, 2019 at 14:21
  • I added the complete contract code and the basic error message I get when using the function "AuctionEnd". Thanks for your help.
    – Siewi
    Commented Oct 3, 2019 at 10:52
  • Hi, did you got to fix it? Commented Jan 10, 2020 at 18:32

4 Answers 4

2

If you are sending the money to a contract, and not an account address, then the recipient contract must have a "fallback" function to be able to receive ETH.

Fallback functions tend to look as follows:

    function() external payable {}

though you can add logic within the fallback function if you wish.

Using recipient.transfer(...) limits the transfer to 2300 gas. This means, if you put complex logic within the fallback function, that would cost more than 2300 gas, the transferal will revert. In this case to transfer the ETH to the contract you must use .call.value(address(this).balance)() instead of .transfer.

1
  • I want to send the money to an address. I added the contract code and the error message I get after using the "AuctionEnd" function.
    – Siewi
    Commented Oct 3, 2019 at 10:53
1

Okay so I readjusted your contract and added a few things that seemed necessary (P.S I have tested this on remix IDE only)

For ex:

  1. I added a lowest bidder that who's parameters will be set by constructor (i.e you have to pass the values when you deploy the contract)
  2. I created a struct to store information about the bids made and also an array of structs to retain the list of bids with their info

Rest is just some minor changes that were needed with the newer versions of solidity. I did not go beyond your problem to build a fully functioning auction thing. But if you're interested we could do that together.

Here's the code I have written

pragma solidity 0.8.7;
//SPDX-License-Identifier: MIT

contract reverse_auction{
  address payable public auctioneer;
  address payable public lowestBidder;
  uint public auctionEndTime;
  uint public WTP;
  uint public lowestBid;
  bool ended;

struct Bidder{
    address bidder;
    uint32 bid;
}
Bidder[] public bidders; 
//Creating object for struct array.

mapping(address => uint) pendingReturns;

constructor(uint biddingTime, uint32 _amount ) payable{
    auctioneer = payable(msg.sender);
    auctionEndTime = block.timestamp + biddingTime;
    WTP = msg.value;
    lowestBid = WTP;
    ended = false;
    bidders.push(Bidder(msg.sender, _amount));
    //Pushing a bid into the bidders array of structs
}

function bid() public payable {                                           
    ///insurance deposit (linking with tracking contract!)
    require(block.timestamp <= auctionEndTime,"Auction already ended.");
    require(msg.value < WTP,"Bid exceeds willingness to pay.");
    require(msg.value < lowestBid,"There already is a lower bid.");
    if (lowestBid != 0) {
        lowestBidder.transfer(lowestBid);
        pendingReturns[lowestBidder] += lowestBid;
        lowestBidder = payable(msg.sender);
        lowestBid = msg.value;
    }
}

function AuctionEnd() public {
    require(msg.sender == auctioneer,"Insufficient permission.");
    require(block.timestamp >= auctionEndTime, "Auction not yet ended.");
    require(ended == false, "AuctionEnd has already been called.");
    lowestBidder.transfer(lowestBid*2); 
    ///paying back safety deposit + actual payment (so 2 times lowest bid)
    auctioneer.transfer(address(this).balance);  
    ///rest of the contract balance (WTP-lowest bid) should go back to the auctioneer
    ended = true;
}
 }

Do tell me if any errors you get while running this on remix

0

Because your current balance is 0. You can try to use Low level interactions to send some balance to the contract address. Let me know if that works!

enter image description here

0

There are two reasons for the error you are getting:

  1. The contract's balance is empty.
  2. The address you are going to transfer ether is not payable.

I speculate that the first reason is much more probable. You need to either transfer some ether to your contract via fallback function or deploy the contract with some ether via msg.value in the remix IDE.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.