my english is very bad.i am sorry. I found an example of an auction where you can pay with ethers. I would like to pay with ERC20 tokens. Please tell me how to do this in the placeBID () and FinalizeAuction () functions. I display it all through web3js on the browser. I also created my token and transferred them to all accounts via metamask. I am a noob in this thread. I run everything on the ropsten test environment. Thanks in advance.


pragma solidity 0.5.3;
import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol";

import "ballot_test.sol";

contract AuctionBox{

Auction[] public auctions; 

function createAuction (
    string memory _title,
    uint _startPrice,
    string memory _description
    ) public{
    // set the new instance
    Auction newAuction = new Auction(msg.sender, _title, _startPrice, _description);
    // push the auction address to auctions array

function returnAllAuctions() public view returns(Auction[] memory){
    return auctions;

contract Auction {

TRC20 trc20;
using SafeMath for uint256;
//AuctionBox trc20;
address payable private owner; 
string title;
uint startPrice;
string description;

enum State{Default, Running, Finalized}
State public auctionState;

uint public highestPrice;
address payable public highestBidder;
mapping(address => uint) public bids;

/** @dev constructor to creat an auction
  * @param _owner who call createAuction() in AuctionBox contract
  * @param _title the title of the auction
  * @param _startPrice the start price of the auction
  * @param _description the description of the auction

    address payable _owner,
    string memory _title,
    uint _startPrice,
    string memory _description

    ) public {
    // initialize auction
    owner = _owner;
    title = _title;
    startPrice = _startPrice;
    description = _description;
    auctionState = State.Running;

modifier notOwner(){
    require(msg.sender != owner);

/** @dev Function to place a bid
  * @return true

function placeBid() public payable notOwner returns(bool) {
    require(auctionState == State.Running);
    require(msg.value > 0);
    // update the current bid
    // uint currentBid = bids[msg.sender] + msg.value;
    uint currentBid = bids[msg.sender].add(msg.value);
    //uint currentBid = balanceOf[msg.sender];
    require(currentBid > highestPrice);
    // set the currentBid links with msg.sender
    bids[msg.sender] = currentBid;
    //balanceOf[msg.sender] = currentBid;
    // update the highest price
    highestPrice = currentBid;
    highestBidder = msg.sender;
    //trc20.transferFrom(msg.sender, owner, 100);
    return true;

function finalizeAuction() public{
    //the owner and bidders can finalize the auction.
    require(msg.sender == owner || bids[msg.sender] > 0);

    address payable recipiant;
    uint value;

    // owner can get highestPrice
    if(msg.sender == owner){
        recipiant = owner;
        value = highestPrice;
    // highestBidder can get no money
    else if (msg.sender == highestBidder){
        recipiant = highestBidder;
        value = 0;
    // Other bidders can get back the money 
    else {
        recipiant = msg.sender;
        value = bids[msg.sender];
    // initialize the value
    bids[msg.sender] = 0;
    //transfer(recipiant, 100);
    auctionState = State.Finalized;

/** @dev Function to return the contents od the auction
  * @return the title of the auction
  * @return the start price of the auction
  * @return the description of the auction
  * @return the state of the auction 

function returnContents() public view returns(        
    string memory,
    string memory,
    ) {
    return (


pragma solidity 0.5.3;

contract TRC20{
     string public name;
     string public symbol;
     uint8 public decimals = 8;
     uint256 public totalSupply;

 mapping (address=> uint256) public balanceOf;
 mapping(address=> mapping(address=>uint256)) public allowance;

 event Transfer(address indexed from, address indexed to, uint256 value);
 event Approval(address indexed _owner, address indexed _spender, uint256 value);
 event Burn(address indexed from, uint256 value);

 uint256 initialSupply = 1000000;
 string tokenName = 'CodeXpertToken';
 string tokenSymbol = 'CDX';

 constructor() public{

     totalSupply = initialSupply*10**uint256(decimals);
     balanceOf[msg.sender] = totalSupply;
     name = tokenName;
     symbol = tokenSymbol;


 function _transfer(address _from, address _to, uint _value) internal{

     require(balanceOf[_to] + _value>=balanceOf[_to]);
     uint previousBalances = balanceOf[_from] + balanceOf[_to];

     balanceOf[_from] -= _value;
     balanceOf[_to] +=_value;
     emit Transfer(_from, _to, _value);


 function transfer(address _to, uint256 _value) public payable returns (bool success){
     _transfer(msg.sender, _to, _value);
     return  true;

 function transferFrom(address _from, address _to, uint256 _value) public returns(bool success){

     require(_value<= allowance[_from][msg.sender]);
     _transfer(_from, _to, _value);
     return true;

 function approve(address _spender, uint256 _value) public returns (bool success){
     allowance[msg.sender][_spender] = _value;
     emit Approval(msg.sender, _spender, _value);

     return true;


You can modify placeBid like this:

function placeBid(uint amount) public notOwner returns(bool) {
    require(auctionState == State.Running);

    // update the current bid
    uint currentBid = bids[msg.sender].add(amount);
    require(currentBid > highestPrice);

    // set the currentBid links with msg.sender
    bids[msg.sender] = currentBid;

    // update the highest price
    highestPrice = currentBid;
    highestBidder = msg.sender;

    // Move to tokens to contract address
    trc20.transferFrom(msg.sender, address(this), amount);

    return true;


  • Pass amount of tokens as parameter
  • Remove payable modifier
  • Transfer tokens to contract address
  • Thanks for the answer. I have a question, how do I know if the sender has a token? how to contact the wallet where there are tokens? thanks. I think that tokens are a contract, so to pay with tokens you need to refer to the contract that created the tokens. Am i right? in my code, I don’t refer specifically to the contract, but just import the file. Is this correct? Feb 3 '20 at 7:07
  • when I run the 'placeBid ()' function the error "Gas estimation failed " Feb 3 '20 at 10:06
  • @malysh To obtain the token balance you call trc20.balanceOf(<address>). A contract usualy don't do that since trc20.transferFrom() will fail if you don't have enough balance. If you want to use an ERC20 it is enough to include the interface, for example OpenZeppelin's IERC20, then assign the address to a variable IERC20 token = 0x123412341234...;. In order to use transferFrom the owner has to approve the contract address.
    – Ismael
    Feb 3 '20 at 15:22
  • Thanks for taking the time. Sorry if the question is dumb. I deployed a TRC20 contract that creates tokens and deployed an AuctionBox contract that creates an auction. Can I use TRC20 tokens for an auction? I think I do not have access to these tokens through the Auction contract. You can check your placeBid () function where the error may be most likely, I tried but couldn’t (thanks. I still get the "Gas estimation errored" error when I run the placeBid () function Feb 4 '20 at 5:25
  • @malysh Did you call approve? In order to allow the contract to use your tokens you have to approve its address. Something like trc20.approve(<auctionBoxAddress>, <amount>, { from: <tokensOwnerAddress> })
    – Ismael
    Feb 4 '20 at 14:45

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