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?
2 Answers
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?– ZedCommented Mar 21, 2021 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 Commented Mar 21, 2021 at 19:57
-
-
@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! Commented Mar 22, 2021 at 8:51