3

I have created an ERC20 token and want to make it payable with DAI.

I read some of the related questions but did not found any proper answer.

As dai is an ERC20 token so, how can I accept any token as payment instead of ether?

function () external payable {}

this accepts only ether, right?

sorry in advance for my English and little understanding of solidity

  • Your users should call the approve function on the DAI contract, passing to it your contract address as the custodian (i.e., the one being approved). They should do so before they call your contract's buy function, which will first call the transferFrom function on the DAI contract, passing to it msg.sender as the address to transfer DAI tokens from, address(this) as the address to transfer DAI tokens to, and the desired amount (which you would need to calculate, I suppose based on the amount that your user wants to buy (which the user will also need to pass to your buy function)). – goodvibration Jan 12 at 18:42
  • Of course, if you use address(this) as the address to transfer DAI tokens to, then it means that the tokens will be transferred to your contract, and since you don't have a private key for it, you'll need to implement an internal mechanism (function) which will allow you to extract those tokens. Alternatively, instead of address(this) you can you some state-variable of address type, which you can preconfigure somewhere in your contract (for example, in the constructor). – goodvibration Jan 12 at 19:29
2

Here is an example of how you can achieve this:

IERC20 public daiInstance;
uint256 public totalSupply;
mapping(address => uint256) public balances;

constructor(IERC20 _daiInstance) public {
    daiInstance = _daiInstance;
}

function buyXXX(uint256 daiAmount) external {
    uint256 xxxAmount = toXXX(daiAmount);
    bool success = daiInstance.transferFrom(msg.sender, address(this), daiAmount);
    require(success, "buy failed");
    totalSupply = totalSupply.add(xxxAmount);
    balances[msg.sender] = balances[msg.sender].add(xxxAmount);
}

function sellXXX(uint256 xxxAmount) external {
    uint256 daiAmount = toDAI(xxxAmount);
    totalSupply = totalSupply.sub(xxxAmount);
    balances[msg.sender] = balances[msg.sender].sub(xxxAmount);
    bool success = daiInstance.transfer(msg.sender, daiAmount);
    require(success, "sell failed");
}

function toXXX(uint256 daiAmount) internal view returns (uint256) {
    // do some logic here
}

function toDAI(uint256 xxxAmount) internal view returns (uint256) {
    // do some logic here
}

Before calling your buyXXX function, your users will need to call the approve function on the DAI contract, passing to it your contract address as the custodian (i.e., the one being approved).

Of course, since you use address(this) as the destination to transfer the user's DAI tokens to, those tokens will be transferred to your contract. And since you don't have a private key for it, you'll need to implement an internal mechanism (function) which will allow you to extract those tokens. Alternatively, instead of address(this), you can add to your contract a state-variable of address type, which you will be able pre-configure somewhere in your contract (for example, in the constructor).

| improve this answer | |
  • is daiInstance is an address of DAI smart contract? – iamsujit Jan 16 at 7:54
  • @iamsujit: Yes. You could technically deploy several DAI smart contracts. We typically refer to the source code as "contract", and to every deployed entity as "instance". Because in many cases there is no sense in deploying more than one instance of a given contract (for example, if the contract represents a token), people often refer to both things (the source code and the deployed byte-code) as "contract". – goodvibration Jan 16 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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