I’m learning how to deploy a defi contract and following the step of deploying a series of contracts from yearn. All of the contract deployments are fine but the following test step of staking ycurvefi lp token into the reward contract is failed. The following are all the contracts addresses:
ycurvefi contract ->0x66e795d4cc98a823042456f9e1920236597f81d3
ycurevefireward contract ->0xF7F3dB45AD4558AF3331530Ab058Ef5A782318E4
Environment
I am using , metamask , solidity 0.5.16, remix to do the test.
Details
I’m not sure whether there is an issue with the contract rule. But I think I can stake some lp tokens at least. I have checked the topic of How to use a token transfer function into another function ? [ ERC20 ] But it can not answer my question. I think I’ve done token approval in advance and then start to stake token with the same account. but it still fails to send the lp token. I’m confused that whether I’ve done the right step to send ERC20 token or not.
Code to reproduce
The error message I got in remix interface is: Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending? gas required exceeds allowance (10000000) or always failing transaction
And the step I’ve done is:
approve with account and amount in Ycurve.fi contract
stake directly with the same account and amount in remix interface.
function stake(uint256 amount) public {
_totalSupply = _totalSupply.add(amount);
_balances[msg.sender] = _balances[msg.sender].add(amount);
y.safeTransferFrom(msg.sender, address(this), amount);
}
function stake(uint256 amount) public updateReward(msg.sender) {
require(amount > 0, "Cannot stake 0");
super.stake(amount);
emit Staked(msg.sender, amount);
}
P.S the y is ycurvefi contract address.
I think the problem is simple. But cause I am a newer in smart contract that I don’t know where is the problem. Please help
Answer the question by my own.
The mistake I took is approve the address of my own private account instead of the reward contract address.
After operating correctly, everything is gone fine.
Another problem emerged when I try to get my reward. The error message is the same as what I’ve posted on this topic. Although I tried to approve the reward contract address on ycn contract, It didn’t work. As written in the following code, the reward will be transferred from ycn contract to the reward owner. I’ve checked the original code of ERC20, but I didn’t find the approve function in the process of transferring. So, I have no idea what’s happened this time.
function getReward() public updateReward(msg.sender) {
uint256 reward = earned(msg.sender);
if (reward > 0) {
rewards[msg.sender] = 0;
ycn.safeTransfer(msg.sender, reward);
emit RewardPaid(msg.sender, reward);
}
}
Thanks! it works. I thought the reward contract will call the transfer function from the reward token contract. Could you please explain why I need to deposit some tokens in advance? In my opinion, the reward contract call the transfer function from the reward token contract should be fine.
It is because the reward contract does a transfer, so the contract has to have enough tokens to transfer. (It calls SafeERC20.safeTransfer which calls IERC20.transfer)
Summary: The logic and code of the contract are fine. As @abcoathup said: The issue appears to be that the reward contract doesn’t have any reward tokens (checking the token balance of the reward contract).