I'm trying to develop a staking contract. All of the guides I've seen utilize either payable (ETH) or a newly created token. How can I import an existing token (presumably via address) into my contract? Also, what is the easiest way to approve the token so I can utilize the transferFrom() function?

  • Welcome! Could you please give an example of what you've written so far, or of some psuedocode trying to accomplish what you're looking for? Mar 21 '21 at 8:36

For importing an existing token, you need to import the token's contract which should be available publically. You can refer to their documentation or GitHub to find that contract, directly import that, and start using it. For example, for using DAI token in your contract, refer to this: https://github.com/makerdao/developerguides/blob/master/dai/dai-token/dai-token.md#token-contract


This is the approve function from the OpenZeppelin ERC20 contract (link):

function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;

The OP's question could be interpreted in two ways, either that the staking contract has a token (is itself an ERC20 contract), and needs to approve another token to spend contents of the staking pool's token. That would involve calling the staking contract's approve function, using code something like:

stakingContract.approve(tokenAddress, <AMOUNT_TO_APPROVE>)

The question could also mean that the staking contract needs to be approved by a user to spend some other token. If this is the case, there may be a misunderstanding - this doesn't happen by "importing" the other token contract into the staking pool's contract, it happens in the token's contract. The user needs to call the token contract, and approve the staking pool there. In Ethers.js pseudocode:

tokenContract.connect(user).approve(stakingPoolAddress, <AMOUNT_TO_APPROVE>);

Depending on your codebase, you may need to call the token contract directly from the staking contract. You'll need either the source code of the token contract you wish to call, or an interface of it, or at the very least an interface that defines the functions you need to interact with (though the latter is likely not advisable). (Here's the link to Vyper's Interfaces, if you prefer Vyper to Solidity.)

To break down exactly how using the interface to interact with the contract works, let's say the token's interface contract is called Foo, and the file for the Foo contract is in the same directory as your staking pool at compile time:

pragma solidity ^0.8.2;

import "./Foo.sol";

contract StakingPool {
    Foo private fooContract

    constructor(address fooAddress) {
        fooContract = Foo(fooAddress);

    function approveStakingPoolOnFoo(uint256 amount) public returns(bool) {
        require(fooContract.approve(msg.sender, address(this), amount),
            "approveOnFoo:approval failed");
        return true;

To break it down, the contract is imported, then the contract name ("Foo") can be used as a data type to create a variable that this contract will treat as a representation of the contract you wish to interact with. In the example, we tell the staking contract in the constructor what the address of the token contract is, and tell it to treat the code at that address like a Foo. (That's the fooContract = Foo(fooAddress); line.) Then we can use that to call functions on the Foo contract - the example given is for Approve, though it is equally applicable to balanceOf and any other public or external function.

Note that oftentimes calls to another contract don't need to be done through the actual contract, but can be done instead through the web interface using a web3 library. A lot depends on your specific case.

Hope that's helpful!

  • The latter interpretation is correct, however, don't I still need to import the other token (ie DAI) into my staking contract in order to calculate balance and rewards?
    – Zed
    Mar 21 '21 at 14:32
  • @Zed not 100% sure what you mean by importing, but I threw in a piece about calling contracts from contracts, hope it helps
    – Linum Labs
    Mar 21 '21 at 19:57
  • This answers my question, thanks
    – Zed
    Mar 21 '21 at 21:29
  • @Zed Great! It would be a big help for us if you could upvote the answer (the up arrow) and also accept it as the answer (the checkmark right under the arrows). We're just getting started with this account, and every bit helps!
    – Linum Labs
    Mar 22 '21 at 8:51

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.