Skip to main content
added what I think the OP was looking for in comments
Source Link
Linum Labs
  • 1.5k
  • 6
  • 18

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!

Hope that's helpful!

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!

Source Link
Linum Labs
  • 1.5k
  • 6
  • 18

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>);

Hope that's helpful!