I'm making a staking dApp (tutorial project) and my withdraw and reward function that is to be called when the msg.sender wants to stop staking doesn't work well. The function calls and returns a variable in remix but theres not transfer of the reward token(token to be paid as interest for staking), same goes for the token to be staked (staked token) and the lp token (token used to know the amount staked). Ive been on this issue for the past few days and i must say im frustrated so please you guys, help a noob out. The contract code is below. the buggy function, withdrawAndReward() is the last function in the code.

pragma solidity^ 0.4.26;

import "./IERC20.sol";

contract stakingContract {

IERC20 public staketokenAdd;
IERC20 public lptokenAdd;
IERC20 public rewardtokenAdd;
uint StakeTokenBal;
uint totalLPbal;
uint RewardTokenBal;
address stakingContractAdd = address(this);
uint StakeTokenBalBeforeNewStake;
address staker;
uint lptokenBalOfSender;
uint amountStaked;
uint _amountStaked;
uint interest;
uint StakeTokenBalAfterNewStake;
uint StakingStarts; 
uint StakeTimeDifference;
uint timeOfStaking;
uint timeOfWithdrawal;
uint unclaimedTokens;
uint withdrawalAmount;

constructor(IERC20 _StakeToken, IERC20 _RewardToken, IERC20 _LPToken){

    staketokenAdd =_StakeToken;
    rewardtokenAdd = _RewardToken;
    lptokenAdd = _LPToken;


function getStakeTokenBalofContract() public view returns(uint StakeTokenBal){
    StakeTokenBal= staketokenAdd.balanceOf(stakingContractAdd);

function getLPTokenBalofContract() public view returns(uint totalLPbal){
    totalLPbal = lptokenAdd.balanceOf(stakingContractAdd);

function getRewardTokenBalofContract() public view returns(uint RewardTokenBal){
   RewardTokenBal = rewardtokenAdd.balanceOf(stakingContractAdd);

// set the amount to be staked
function setAmountToStake(uint _amountStaked) public{
    amountStaked = _amountStaked; 

// call to get the amount staked
function getStakedAmount() public view returns(uint){
    return amountStaked;

// set the time staking starts
function TimeStakingOnContractStarts( uint _StakingStarts){
    StakingStarts = _StakingStarts;

// call function to get the set time staking started
function getTimeStakingOnContractStarts() public view returns(uint){
    return StakingStarts;

function StakeTokenBalanceBeforeNewStake() public view returns (uint StakeTokenBalBeforeNewStake){
    StakeTokenBalBeforeNewStake = staketokenAdd.balanceOf(address(this));

function StakeTokenBalanceAfterNewStake() public view returns(uint StakeTokenBalAfterNewStake){
    StakeTokenBalAfterNewStake = staketokenAdd.balanceOf(address(this));
    return StakeTokenBalAfterNewStake;
function stake() public {
    // get the stake token bal of contract before receiving a stake
    // transfer the stake token to the staking contract 
    staketokenAdd.transferFrom(msg.sender, address(this), amountStaked);
    //send lp tokens to the function caller. the lp tokens are evidence of amount of tokens staked.
    lptokenAdd.transfer(msg.sender, amountStaked);
    //check the stake token bal of the contract after the stake
    //get the time difference from when msg.sender staked and when staking contract has been open for staking
    StakeTimeDifference = now - StakingStarts;
    //time tokens were staked  
    timeOfStaking = now;


function lptokenBalOfCaller() public view returns (uint lptokenBalOfSender){
    lptokenBalOfSender = lptokenAdd.balanceOf(msg.sender);

function withdrawAndReward( uint _withdrawalAmount) public view returns (uint unclaimedTokens){ 
    withdrawalAmount = _withdrawalAmount;
     //make sure lptokenBalOfSender is greater or le ss than the withdrawalAmount
    require(withdrawalAmount <= lptokenAdd.balanceOf(msg.sender), 'withdrawal amount too large, larger than your staked tokens');
    //transfer lptoken to the contract
    lptokenAdd.transferFrom(msg.sender, address(this), withdrawalAmount);
    // transfer staked tokens back to owner 

    staketokenAdd.transfer(msg.sender, withdrawalAmount);
    //get the time withdrawal is initiated; 
    timeOfWithdrawal = now;
    // calculate interest to be paid as reward tokens 
    uint a  = timeOfStaking -  StakingStarts;
    uint aa =  timeOfWithdrawal - timeOfStaking;
    uint ab = a + aa;
    uint b = ab / withdrawalAmount;
    interest = b;
    //transfer reward tokens to owner, they serve as interest on the Stake
    //tranfer reward token due to the caller 
    rewardtokenAdd.transfer(msg.sender, interest);
    // get the amount of tokens left unclaimed after Staking
    unclaimedTokens = amountStaked - withdrawalAmount;  


1 Answer 1


Not enough rep to comment but I think

  1. you should use the SafeMath library to add / substract and divide.

The issue looks like its with initialization of either :

  • the balance amount (point above) or
  • of rewardtokenAdd

How are you calling the constructor? Does the balanceOf function work?

  • i deployed in remix and not with truffle so its pretty easy to put in the constructor arguments. the balance of function works, i've tested it. i tried using the safe math library but didnt work too. that was when i got tired.. or maybe i dont know how to use libraries well. Commented Nov 27, 2020 at 12:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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